Oracle字符串聚合

Mil*_*ton 1 sql oracle oracle11g string-aggregation

我的表结构看起来像这样,我是这个领域的新手.我知道基本的问题.但这对我来说很复杂.请帮我这样做.

表结构

  Customer          Product         piriority
    10001           Main_product    1
    10001           Sub_product1    2
    10001           Sub_product2    2
    10001           Sub_product3    2
    10001           Sub_product4    2
    10002           Main_product    1
    10002           Sub_product1    2
    10002           Sub_product2    2
Run Code Online (Sandbox Code Playgroud)

预期产出:

Customer        Main_Product    Sub_product
10001           Main_product    Sub_product1,Sub_product2,Sub_product3,Sub_product4
10002           Main_product    Sub_product1,Sub_product2
Run Code Online (Sandbox Code Playgroud)

Ben*_*Ben 5

我将假设PRIORITY当有"主要产品"时,该列始终为1,而在任何其他时间都不会为1.从您的数据看,每个客户看起来只有一个"主要"产品.我会假设这是真的.如果不是那么你应该有另一列来区分产品组.您只需将其添加到下面即可.

复杂/有效的答案可能如下:

select customer
     , max(product) keep (dense_rank first order by priority) as main_product
     , listagg(case when priority = 2 then product end, ', ')
         within group (order by product) as sub_product
  from products
 group by customer
Run Code Online (Sandbox Code Playgroud)

SQL小提琴

对于每个客户,该PRODUCT列假定每个客户都有一个主要产品,然后按优先顺序获得第一个产品.第二列仅占优先级为2的位置,并使用字符串连接函数LISTAGG()将您的值连接在一起.

我强烈推荐Rob van Wijk 关于KEEP条款博客文章.

更标准的SQL解决方案如下所示:

select a.customer, a.product as main_product
     , listagg(b.product, ', ') within group (order by b.product) as sub_product
  from products a
  join products b
    on a.customer = b.customer
 where a.priority = 1
   and b.priority = 2
 group by a.customer, a.product
Run Code Online (Sandbox Code Playgroud)

即找到优先级为1的所有内容,使用它来生成两行,然后获取优先级为2的所有内容并聚合它们.