DB2 v9.5基于CASE结果批量合并行数据至单列的查询问题
解决DB2 v9.5中按分组拼接多行字符串的问题
我来帮你搞定这个DB2里的分组拼接需求!你之前的查询问题在于,用MAX(CASE...)只能提取单个值,没法把多行的Reference拼接起来,而XMLAGG的用法需要调整才能得到你想要的格式。
正确的查询语句
针对你的需求,我们可以结合MAX(CASE)提取Code='A'的Reference,再用XMLAGG来拼接其他Code的Reference,具体SQL如下:
SELECT t1.ContractId, MAX(CASE WHEN t1.Code = 'A' THEN t1.Reference END) AS "Reference with Code A", -- 处理非A类型的Reference拼接,去掉末尾多余的逗号和空格 CASE WHEN COUNT(CASE WHEN t1.Code != 'A' THEN 1 END) > 0 THEN SUBSTR( XMLAGG(XMLELEMENT(NAME e, t1.Reference || ', ') ORDER BY t1.Code).GETCLOBVAL(), 1, LENGTH(XMLAGG(XMLELEMENT(NAME e, t1.Reference || ', ') ORDER BY t1.Code).GETCLOBVAL()) - 2 ) ELSE NULL END AS "Other References" FROM Table1 t1 GROUP BY t1.ContractId -- 只保留存在Code='A'的ContractId,和你的示例输出一致 HAVING MAX(CASE WHEN t1.Code = 'A' THEN 1 END) = 1;
代码解释
- 提取Code='A'的Reference:用
MAX(CASE...)配合GROUP BY,每个ContractId只会保留一行,自动提取出对应Code='A'的Reference(如果存在多个A的话会取最大值,你可以根据需求换成MIN或者其他聚合函数)。 - 拼接其他Reference:
XMLAGG是DB2 v9.5中用来聚合字符串的函数,我们用它把每个非A的Reference后面加上,,再拼接成一个长字符串。- 用
SUBSTR去掉最后面多余的,,避免末尾出现无效符号。 - 外层的
CASE用来判断当前ContractId是否有非A的记录,没有的话返回NULL。
- 过滤结果:
HAVING子句用来筛选出至少包含一条Code='A'记录的ContractId,和你给出的示例输出匹配。
关于你之前的尝试
- 你最初的查询用
MAX(CASE...)处理非A记录时,MAX只能返回单个值,所以没法拼接所有符合条件的行,这就是为什么你得到了多行结果(可能是你实际执行时没正确执行GROUP BY?正常GROUP BY ContractId后每个ContractId只会有一行)。 - 如果你之前用XMLAGG没成功,大概率是没处理末尾的逗号,或者没结合聚合函数和分组逻辑。
注意点
看到你给出的期望输出中,ContractId13的Other References包含了其他ContractId的记录(比如asdfa是ContractId15的),这看起来不符合按ContractId分组的逻辑。上面的查询是按每个ContractId自己的非A记录拼接的,如果你确实需要把所有非A的记录不管所属ContractId都放在一起,那需要调整查询逻辑,比如去掉GROUP BY或者做跨表拼接,但这通常不是这类需求的常规用法。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

