繁体   English   中英

Oracle SQL有条件将行聚合到列listagg中

[英]Oracle SQL aggregate rows into column listagg with condition

我有以下-简化-表格布局:

  • TABLE块(ID)
  • 表格内容(id,blockId,顺序,数据,类型)

content.blockIdblocks.id的外键。 想法是,在内容表中,一个块具有许多不同类型的内容条目。

我现在正在寻找一个查询,该查询可以为我提供基于blockId的聚合,其中将3种不同类型的所有内容条目连接在一起并放入相应的列中。

我已经启动并找到运行良好的listagg函数,我做了以下声明,并在列中列出了所有内容条目:

SELECT listagg(c.data, ',') WITHIN GROUP (ORDER BY c.order) FROM content c WHERE c.blockId = 330;

现在,连接字符串现在在一列中包含了该块的所有data元素。 我要实现的是根据类型将其放入单独的列中。 例如以下内容content是这样的:

  • 1,1,0,“ content1”,“ FRAGMENT”
  • 2、1、1,“ content2”,“ BULK”
  • 3、1、3,“ content4”,“ FRAGMENT”
  • 4、1、2,“ content3”,“ FRAGMENT”

现在我想获得2列作为输出,一列是FRAGMENT,一列是BULK,其中FRAGMENT包含“ content1; content3; content4”,而BULK包含“ content2”

是否有一种有效的方法来实现这一目标?

您可以使用case

SELECT listagg(CASE WHEN content = 'FRAGMENT' THEN c.data END, ',') WITHIN GROUP (ORDER BY c.order) as fragments,
       listagg(CASE WHEN content = 'BULK' THEN c.data END, ',') WITHIN GROUP (ORDER BY c.order) as bulks
FROM content c
WHERE c.blockId = 330;

或者,如果您希望它更具动态性,则可以调整结果。 请注意,这仅适用于Oracle 11.R2。 这是一个示例,显示如下:

select * from
(with dataSet as (select 1 idV, 1 bulkid, 0 orderV, 'content1' dataV, 'FRAGMENT' typeV from dual union
                 select 2, 1, 1, 'content2', 'BULK' from dual union
                 select 3, 1, 3, 'content4', 'FRAGMENT' from dual union
                 select 4, 1, 2, 'content3', 'FRAGMENT' from dual)
select typeV, listagg(dataSet.dataV ,',')  WITHIN GROUP (ORDER BY orderV) OVER (PARTITION BY typeV) dataV from dataSet)
pivot
(
   max(dataV)
   for typeV in ('BULK', 'FRAGMENT')
)

O / P

Bulk      |  FRAGMENT
-----------------
content2  |  content1,content3,content4

这里重要的事情:

OVER (PARTITION BY typeV) :这类似于OVER (PARTITION BY typeV)的group by,将具有相同typeV所有内容typeV

for typeV in ('BULK', 'FRAGMENT') :这将收集BULKFRAGMENT的数据,并为每个生成单独的列。

max(dataV)仅提供聚合功能,否则数据透视将无法工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM