我必须“从概念上”写这个问题,因为我不确定实际采用哪种方法。我的提问方式可能会解决XY问题-如果您看到其他建议,请提出其他建议。
我正在对已经投入生产的数据库编写报告查询。考虑下表(类似于我当前的结果集):
Id | Code1 | Code2 | Code3 | Code4 | Code5
-----------------------------------------------------------
1 1 2 3 4 5
1 2 3 4 5 6
2 1 null null null null
所有代码在字面上(作为数据类型)和概念上(例如,对于相同类型的事件等,都表示相同的“种类”)都是相同的“类型”。显然,这些数据没有正确归一化,但是我仍然需要对其进行转换。
我想编写一个查询,对ID进行“分组”,并返回5个代码列中所有唯一代码的集合。
最终,我的目标是将表格转换为:
Id Codes
1 [1, 2, 3, 4, 5, 6]
2 [1]
([]
至少在概念上表示某种集合,表或列表类型)
(实际上,我需要结合这些代码进行快速查找,因此“实际”结果应如下所示)
Id CodeStrings
1 [Foo, Bar, Baz, Bon, Fizz, Buzz]
2 [Foo]
您能描述一个模式,让我每行形成一个“集合”并进行汇总吗?
答案 0 :(得分:1)
我先取消数据透视表,然后使用For xml path连接按ID分组的行。
答案 1 :(得分:1)
您需要取消透视和重新聚合。在SQL Server 2017+中,这非常简单:
select t.id, string_agg(c.code, ',')
from t cross apply
(select distinct v.code
from (values (code1), (code2), (code3), (code4), (code5)
) v(code)
where v.code is not null
) c;
在早期版本中,您可以使用for xml path
:
select t.id, stuff(c.codes, 1, 1, '') as codes
from t cross apply
(select distinct ',' + v.code
from (values (code1), (code2), (code3), (code4), (code5)
) v(code)
where v.code is not null
for xml path ('')
) c(codes)
答案 2 :(得分:0)
仅5个,最简单的选择可能是:
Select ID, '[' + ISNULL(Code1, '')
+ ISNULL(' ,' + Code2, '')
+ ISNULL(' ,' + Code3, '')
+ ISNULL(' ,' + Code4, '')
+ ISNULL(' ,' + Code5, '') + ']'
From MyTable
请注意,如果代码以数字形式存储,则可能需要将代码用cast
或convert
包装到varchar
中。