我有以下查询真正杀死了性能,并想知道它们对xml reader子查询有什么替代方法。此查询的目的是使用某些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/>
答案 0 :(得分:3)
虽然这个替代方案会跳过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
由于每行所需的函数,这可能表现不佳。一个可能更快的变体是将函数编写为表值函数,并在join子句中通过CROSS APPLY
引用它。
答案 1 :(得分:3)
我认为您会在外部查询中跳过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 User-Defined Aggregate Function连接。
其他替代方案可以在Concatenating Row Values in Transact-SQL找到。