用逗号分隔的 Oracle sql 透视值

Posted

技术标签:

【中文标题】用逗号分隔的 Oracle sql 透视值【英文标题】:Oracle sql pivoting values separated by commas 【发布时间】:2021-04-09 08:09:55 【问题描述】:

我有以下输入

ID LOTYP PROID LOCKR
XXXXX 06 01 Y
XXXXX 06 02 X
XXXXX 06 02 S
XXXXX 06 01 R
XXXXX 02 01 Y
XXXXX 02 02 X
XXXXX 02 02 S
XXXXX 02 01 R
YYYYY 06 01 Y
YYYYY 06 02 X
YYYYY 06 02 S
YYYYY 06 01 R
YYYYY 02 01 Y
YYYYY 02 02 X
YYYYY 02 02 S
YYYYY 02 01 R

我想要下面的输出

ID 0201 0202 0601 0602
XXXXX R, Y S, X R, Y S, X
YYYYY R, Y S, X R, Y S, X

我可以分别进行 pivot 和 listagg,但我很难将它们组合起来以产生所需的输出。

【问题讨论】:

【参考方案1】:

您可以为id 和连接的 (lotyp||proid) 列旋转分组结果,例如

SELECT *
  FROM
  (
    SELECT id,lotyp||proid As title,
           LISTAGG(lockr,',') WITHIN GROUP (ORDER BY lotyp||proid) AS value
      FROM t
     GROUP BY id,lotyp||proid )
 PIVOT (
         MAX(value) FOR title IN ('0201' AS "0201",
                                  '0202' AS "0202",
                                  '0601' AS "0601",
                                  '0602' AS "0602"))   
 ORDER BY id;
ID 0201 0202 0601 0602
XXXXX R,Y S,X R,Y S,X
YYYYY R,Y S,X R,Y S,X

Demo

【讨论】:

谢谢!我没有想到那种方式。现在我不知道该怎么做,假设结果是 R、R、R、R、Y,加上 4R、Y。但我会在另一个问题上提出这个问题。 不客气@JaviTorre。您可以查看this 以获取动态选项。【参考方案2】:

我只是发现条件聚合比pivot简单得多:

SELECT id,
       LISTAGG(CASE WHEN lotyp = '02' AND proid = '01' THEN lockr END, ',') WITHIN GROUP (ORDER BY lockr) as "0201",
       LISTAGG(CASE WHEN lotyp = '02' AND proid = '02' THEN lockr END, ',') WITHIN GROUP (ORDER BY lockr) as "0201",
       LISTAGG(CASE WHEN lotyp = '06' AND proid = '01' THEN lockr END, ',') WITHIN GROUP (ORDER BY lockr) as "0601",
       LISTAGG(CASE WHEN lotyp = '02' AND proid = '01' THEN lockr END, ',') WITHIN GROUP (ORDER BY lockr) as "0601"
FROM t
GROUP BY id ;

没有子查询。只是逻辑清楚地做了你想做的事。

【讨论】:

谢谢!这也是一个很好的解决方案,尽管对于许多 lotyp/proid 组合而言不可扩展。 @JaviTorre 。 . .我不确定您所说的可扩展性是什么意思。条件聚合的运行速度通常与pivot 一样快或更快。另外,这避免了子查询中的聚合,这应该使它更快。

以上是关于用逗号分隔的 Oracle sql 透视值的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL:为列中的每个值创建一个新行,其中更多值用逗号分隔

使用 oracle sql 以逗号分隔的字符串

在 Oracle SQL 中求和逗号分隔值

oracle sql中的动态数据透视

oracle sql中的动态数据透视

如何把SQL数据表中一个字段的值按逗号分隔存入另外一个表,并删除重复记录?