如何拼接同表不同行单元格?SQL语句问题求助
解决Oracle中分类行TEXT拼接及重复行问题
首先,我先梳理下你的核心需求:
- 基于
BLTGS1-6的分类逻辑,将BLTUGP为数字(1/2)的行的TEXT,拼接至同分类下上方第一个BLTUGP非数字/空的行的TEXT内容 - 必须保留所有
BLTUGP为空/NULL的行,且原表不能修改
你现有语句的问题分析
你当前的CTE+UNION方案出现重复行,主要有几个原因:
- 第二个CTE的
RIGHT JOIN条件里,u.bltgs6=u.bltgs6是无效条件(恒成立),这会导致每个u行匹配所有符合条件的h行,直接产生重复 - 两个CTE的分组/TEXT生成逻辑不一致:
tbl_wougp用了LISTAGG聚合文本,而tbl_wugp直接取单条bltxt,导致同一分组的行可能在两个CTE中都被输出,UNION后出现重复 RIGHT JOIN会保留所有u行,即使找不到对应的h行,这时候拼接会出现NULL值,不符合你的预期
优化后的解决方案
我们可以利用Oracle的窗口函数LAST_VALUE来精准定位每个数字BLTUGP行对应的父行文本,避免JOIN带来的重复问题,同时统一TEXT的生成逻辑:
WITH base_data AS ( -- 先统一处理所有行的TEXT,和你原逻辑一致用LISTAGG聚合 SELECT bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp, regexp_replace(regexp_replace(LISTAGG(bltxt,' ') WITHIN GROUP (ORDER BY blttkz),'\s+',' '),'¯+','') AS original_text FROM atdata.bip105 WHERE bltspriso = 'DEAT' GROUP BY bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp ), with_parent_text AS ( -- 用窗口函数找到同分类下,当前行之前最近的非数字BLTUGP行的TEXT SELECT *, LAST_VALUE(CASE WHEN NOT REGEXP_LIKE(bltugp, '^[0-9]+$') THEN original_text END IGNORE NULLS) OVER (PARTITION BY bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6 ORDER BY blttkz, bltugp ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS parent_text FROM base_data ) -- 生成最终结果:数字BLTUGP行拼接父文本,其他行保留原文本,同时去重 SELECT bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp, CASE WHEN REGEXP_LIKE(bltugp, '^[0-9]+$') AND parent_text IS NOT NULL THEN TRIM(parent_text || ' ' || original_text) ELSE original_text END AS Text FROM with_parent_text GROUP BY bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp, original_text, parent_text ORDER BY bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp;
方案说明
base_dataCTE:统一对所有分组执行LISTAGG文本聚合,确保所有行的TEXT生成逻辑一致,避免后续重复with_parent_textCTE:PARTITION BY bltgs1-6确保只在同一分类内查找父行LAST_VALUE(... IGNORE NULLS)会跳过BLTUGP为数字的行,精准定位当前行之前最近的非数字BLTUGP行的TEXTORDER BY blttkz, bltugp保证排序和你原逻辑一致,确保父行是"上方"的行
- 最终SELECT:
- 对
BLTUGP为数字的行,拼接父文本和当前文本(用TRIM避免多余空格) - 对其他行(空/非数字
BLTUGP)直接保留原文本 - 最后用
GROUP BY去重,避免窗口函数或分组逻辑可能产生的重复行
- 对
这样就能完美实现你的需求,同时解决重复行的问题。
内容的提问来源于stack exchange,提问作者F.Gradl
相关产品推荐
相关产品推荐

