我有以下查询,它确实降低了性能,我想知道xml阅读器子查询有什么替代方案。这个查询的目的是用一些html代码导出数据。
表数据的示例如下:
p_s_id | p_c_id | notes
-----------------------
1 | 1 | this note is really long.
2 | 1 | This is fun.
3 | null | long note here
4 | 2 | this is not fun
5 | 2 | this is not fun
6 | 3 | long note here
我想把所有具有相同p_c_id的不同笔记连接在一起,如下所示。
如有任何其他信息可以提供,请随时评论。
select distinct
p_c_id
,'<br/><br/>'+(select distinct '• ' +cast(note as nvarchar(max)) + ' <br/> '
from dbo.spec_notes_join m2
where m.p_c_id = m2.p_c_id
and isnull(note,'') <> ''
for xml path(''), type).value('.[1]', 'nvarchar(max)') as notes_spec
from dbo.spec_notes_join m
,输出如下所示:
p_c_id | notes
--------------
1 | <br/><br/> • this note is really long. <br/> &bull This is fun <br/>
2 | <br/><br/> • This is not fun. <br/>
3 | <br/><br/> • long note here. <br/>
我认为你会得到稍微更好的性能,你跳过distinct
在外部查询和做一个group by p_c_id
代替。
select p_c_id,
'<br/><br/>'+(select distinct '• ' +cast(note as nvarchar(max)) + ' <br/> '
from dbo.spec_notes_join m2
where m.p_c_id = m2.p_c_id and
isnull(note,'') <> ''
for xml path(''), type).value('.', 'nvarchar(max)') as notes_spec
from dbo.spec_notes_join m
group by p_c_id
您也可以尝试使用CLR用户定义聚合函数进行连接。
在Transact-SQL中连接行值可以找到其他替代方法。
虽然这种替代方法跳过了XML,但我不知道它是否提高了性能——如果您可以测试并将结果作为评论发布,我将不胜感激。(它在我的快速模拟中工作,你可能需要在你自己的结构上做一些小的调试。)
从这个函数开始:
CREATE FUNCTION dbo.Testing
(
@p_c_id int
)
RETURNS varchar(max)
AS
BEGIN
DECLARE @ReturnString varchar(max)
SELECT @ReturnString = isnull(@ReturnString + ' <br/> , <br/><br/>• ', '<br/><br/>• ') + Name
from (select distinct note
from spec_notes_join
where p_c_id = @p_c_id
and isnull(note, '') <> '') xx
SET @ReturnString = @ReturnString + ' <br/> '
RETURN @ReturnString
END
GO
,然后嵌入到你的查询中:
SELECT p_c_id, dbo.Testing(p_c_id)
from (select distinct p_c_id
from dbo.spec_notes_join) xx
由于每行都需要调用函数,因此可能执行得很差。一个可能更快的变体是将函数写为表值函数,并在连接子句中通过CROSS APPLY
引用它。