customer_comments
由于数据库设计,我将一些拆分为多行,对于报告,我需要将comments
每个唯一的行合并id
为一行。我之前尝试过使用SELECT 子句和 COALESCE 技巧中的这个分隔列表,但我不记得它并且一定没有保存它。在这种情况下,我似乎也无法让它工作,似乎只能在一行上工作。
数据如下所示:
id row_num customer_code comments
-----------------------------------
1 1 Dilbert Hard
1 2 Dilbert Worker
2 1 Wally Lazy
我的结果需要如下所示:
id customer_code comments
------------------------------
1 Dilbert Hard Worker
2 Wally Lazy
所以对于每个row_num
实际上只有一行结果;注释应按row_num
. 上面的链接SELECT
技巧可以将特定查询的所有值作为一行获取,但我不知道如何使它作为SELECT
吐出所有这些行的语句的一部分工作。
我的查询必须自己遍历整个表并输出这些行。我没有将它们组合成多列,每行一个,所以PIVOT
似乎不适用。
这对于相关子查询来说是相对微不足道的。您不能使用您提到的博客文章中突出显示的 COALESCE 方法,除非您将其提取到用户定义的函数中(或者除非您一次只想返回一行)。以下是我通常这样做的方式:
如果您遇到注释中的数据可能包含不安全的 XML 字符 (
>
,<
,&
) 的情况,您应该更改此:对于这种更精细的方法:
(确保使用正确的目标数据类型,
varchar
或nvarchar
,和正确的长度,并在所有字符串文字前加上N
if usingnvarchar
。)如果您被允许在您的环境中使用 CLR,这是为用户定义的聚合量身定制的案例。
特别是,如果源数据非常大和/或您需要在应用程序中做很多此类事情,这可能是要走的路。我强烈怀疑Aaron 解决方案的查询计划不会随着输入大小的增长而很好地扩展。(我尝试向临时表添加索引,但这没有帮助。)
与许多其他事情一样,此解决方案是一种权衡:
编辑:好吧,我去尝试看看这是否真的更好,事实证明,使用聚合函数目前无法满足评论按特定顺序的要求。:(
请参阅SqlUserDefinedAggregateAttribute.IsInvariantToOrder。基本上,您需要做的是
OVER(PARTITION BY customer_code ORDER BY row_num)
聚合时子句ORDER BY
不支持。OVER
我假设将此功能添加到 SQL Server 会引发大量蠕虫,因为在执行计划中需要更改的内容是微不足道的。前面提到的链接说这是为将来使用而保留的,所以这可以在将来实现(不过,在 2005 年你可能不走运)。这仍然可以通过将
row_num
值打包并解析到聚合字符串中来完成,然后在 CLR 对象中进行排序……这看起来很不自然。无论如何,下面是我使用的代码,以防其他人发现这很有用,即使有限制。我将把黑客部分作为练习留给读者。请注意,我使用 AdventureWorks (2005) 作为测试数据。
聚合组装:
用于测试的 T-SQL(省略了启用 CLR 和)
CREATE ASSEMBLY
:sp_configure
这是一个基于游标的解决方案,可以保证评论的顺序
row_num
。(有关表格的填充方式,请参阅我的其他答案。)[dbo].[Comments]