Oracle中按类别分区实现行上方VARCHAR列条件拼接需求
解决方案
你的问题核心是需要同类别内按SEQNCE累积拼接前置行数据,之前用LAG()只能取上一行,无法实现全量前置行的拼接,这里可以用窗口版的LISTAGG(主流关系型数据库如Oracle、PostgreSQL支持)结合分区和范围窗口来满足需求。
通用SQL实现(以Oracle/PostgreSQL为例)
SELECT Column1, catg, flg, SEQNCE, CASE WHEN flg = 1 THEN -- 拼接同catg下所有SEQNCE小于当前行的Column1,再追加当前行 COALESCE( LISTAGG(Column1, '+') OVER ( PARTITION BY catg ORDER BY SEQNCE ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) || '+', '' ) || Column1 ELSE -- flg=0时直接返回当前行的Column1 Column1 END AS res1 FROM dmy_tbl ORDER BY catg, SEQNCE;
逻辑说明
PARTITION BY catg:严格限定拼接范围在同一类别内,类别切换后自动重新开始累积ORDER BY SEQNCE:保证按SEQNCE的顺序拼接前置行数据ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING:指定窗口范围为当前行之前的所有行(不包含当前行)COALESCE:处理当前行是同类别第一行的情况(此时前置行拼接结果为null,用空字符串替代,避免出现多余的+)
MySQL 8.0+适配方案
MySQL不支持窗口版LISTAGG,可以用窗口版GROUP_CONCAT替代:
SELECT Column1, catg, flg, SEQNCE, CASE WHEN flg = 1 THEN CONCAT( COALESCE( GROUP_CONCAT(Column1 ORDER BY SEQNCE SEPARATOR '+') OVER ( PARTITION BY catg ORDER BY SEQNCE ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ), '' ), -- 只有存在前置行时才添加分隔符 IF(GROUP_CONCAT(Column1 ORDER BY SEQNCE) OVER ( PARTITION BY catg ORDER BY SEQNCE ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) IS NOT NULL, '+', ''), Column1 ) ELSE Column1 END AS res1 FROM dmy_tbl ORDER BY catg, SEQNCE;
内容的提问来源于stack exchange,提问作者Bhawana Solanki
相关产品推荐
相关产品推荐

