LISTAGG:小组内的小组

时间:2014-11-25 14:07:04

标签: sql oracle

让我从数据开始,更好地描述我需要的东西。我有一个名为SUPERMARKET的表,其中包含以下字段:

Field 1: StoreID
Field 2: ProductCategory
Field 3: ProductID

数据如下所示:

1, Fruit, Banana
1, Fruit, PineApple
1, Fruit, Strawberry
1, Beverage, Milk
1, Beverage, Chocolate Milk
1, Beverage, Apple Juice
1, Vegetable, beet
2, Vegetable, beet
2, Vegetable, onion
2, Vegetable, Kyle

我希望有这样的观点:

1, Fruit:(Banana, PineApple, Strawberry), Beverage:(Milk, Chocolate Milk, Apple Juice), Vegetable: (beet)
2, Vegetable:(beet, onion, kyle)

Oracle是否有办法显示我正在寻找的信息,如上所述?我试过了:

SELECT "StoreID", LISTAGG("ProductCategory",',') WITHIN GROUP (ORDER BY "ProductCategory") "ProductCategories" FROM SUPERMARKET GROUP BY "StoreID"

但这只列出了:

1, "Fruit,Beverage,Vegetable"
2, "Vegetable"

或者如果我使用ProductID而不是ProductCategory,那么我会得到一个随机显示的产品列表,而不是按类别分组

SELECT "StoreID", LISTAGG("ProductID",',') WITHIN GROUP (ORDER BY "ProductID") "Products" FROM SUPERMARKET GROUP BY "StoreID"

有没有人有诀窍如何解决这个问题?请帮忙。

更新和发布视图:

每个人建议的sql都像魅力一样,直到我试图将完全相同的工作sql放入视图中。出于某种原因,Oracle编译器不喜欢它并抛出错误:

Error(s) parsing SQL:
Unexpected token near *!* in the following:
|| ')', ', ') WITHIN *!*GROUP (
Unexpected token near *!* in the following:
|| ')', ', ') WITHIN GROUP *!*(
Missing expression near *!* in the following:
|| ')', ', ') WITHIN GROUP (
*!*ORDER BY ProductCategory) AS ProductsAndCategories

有谁知道为什么?由于它与我原来的问题有关,我想我会把它放在同一个问题中以便日后参考。

enter image description here

戈登的建议

这实际上是SQL Developer GUI的一个错误。绕过问题 - >使用语句创建视图。

2 个答案:

答案 0 :(得分:4)

进行两级聚合:

SELECT storeId,
       LISTAGG(ProductCategory || ':' || '(' || ProductIds || ')', ', ')
            WITHIN GROUP (ORDER BY ProductCategory) as ProductsAndCategories
FROM (SELECT StoreId, ProductCategory,
             LISTAGG(ProductId, ',') WITHIN GROUP (ORDER BY ProductId) as ProductIds
      FROM SUPERMARKET
      GROUP BY StoreId, ProductCategory
     ) s
GROUP BY StoreId;

答案 1 :(得分:1)

SELECT storeid,
  listagg(a,',') within GROUP (
ORDER BY a)
FROM
  (SELECT storeid,
    productCategory
    ||'('
    ||listagg(productId,',') within GROUP (
  ORDER BY productId)
    ||')' a
  FROM supermarket
  GROUP BY storeid,
    productCategory
  )
GROUP BY storeid