说我有两张桌子:
产品
product_id (other fields are of no concern)
SKU
product_id sku_id color_id color_name (other fields such as size but unimportant)
001 11 5 green
001 12 1 black
001 13 3 red
002 21 1 black
002 22 2 yellow
002 23 8 magenta
002 24 9 turquoise
我需要重写一个查询,该查询获取产品ID列表,其中包含与该产品关联的所有颜色/颜色ID的逗号分隔列表。两个列表中的颜色ID /名称必须具有相同的顺序。
期望的输出:
product_id colorIds colorNames
001 1,3,5 black,red,green
002 1,2,8,9 black,yellow,magenta,turquoise
请注意颜色ID的连续列表'订购地图到颜色名称顺序。
当前输出:
product_id colorIds colorNames
001 1,3,5 green,black,red -- out of order sometimes
002 1,2,8,9 black,yellow,magenta,turquoise
目前使用的查询:
select distinct(p.product_id) as product_id,
(select decode(dbms_lob.SubStr(wm_concat(DISTINCT color_name)),'NO COLOR','','No Color','','no color','',null,'',dbms_lob.SubStr(wm_concat(DISTINCT color_name))) as color_name from sku where product_id = p.product_id) as colorName,
(select decode(dbms_lob.SubStr(wm_concat(DISTINCT color_code)),'000','',dbms_lob.SubStr(wm_concat(DISTINCT color_code))) from sku where product_id = p.product_id) as colorCode
from product p;
我在考虑只是在那些子选择中添加order by子句,但是查询只是错误输出,说缺少右括号 - 奇怪的是似乎没有不匹配的parens。欢迎任何建议。
编辑* 以上查询高度简化。实际上,它与十几个其他表连接以获得与产品相关的其他数据列,其中大多数是非聚合数据。解决方案在主查询中应该没有group by子句,或者建议一种合理的方式来满足这一要求。
答案 0 :(得分:2)
这可能对您有用:
SELECT p.product_id
, LISTAGG(s.color_id, ',') WITHIN GROUP ( ORDER BY s.color_id ) AS colorIds
, LISTAGG(s.color_name, ',') WITHIN GROUP ( ORDER BY s.color_id ) AS colorNames
FROM product p LEFT JOIN ( SELECT DISTINCT product_id, color_id, color_name FROM sku ) s
ON p.product_id = s.product_id
GROUP BY p.product_id
ORDER BY product_id
LISTAGG()
可以在WM_CONCAT()
无法排序的情况下排序(并且它没有记录,等等。)
根据OP对非汇总数据的评论更新
WITH product_colors AS (
SELECT p.product_id
, LISTAGG(s.color_id, ',') WITHIN GROUP ( ORDER BY s.color_id ) AS colorIds
, LISTAGG(s.color_name, ',') WITHIN GROUP ( ORDER BY s.color_id ) AS colorNames
FROM product p LEFT JOIN ( SELECT DISTINCT product_id, color_id, color_name FROM sku ) s
ON p.product_id = s.product_id
GROUP BY p.product_id
)
SELECT t1.other_column, t2.other_column, etc.
FROM table1 t1 JOIN table2 t2 ON ...
JOIN product_colors pc ON ...
答案 1 :(得分:2)
这将实现distinct
效果(您不能将distinct
与listagg
一起使用):
select product_id,
listagg(color_id, ',') within group(order by color_id) as colorids,
listagg(color_name, ',') within group(order by color_id) as colornames
from (select distinct product_id, color_id, color_name from sku)
group by product_id
如果您想显示product
表格中的列和/或您希望在product
表格上展示产品,而不是sku
表格中的产品,则可以使用:
select p.product_id,
listagg(s.color_id, ',') within group(order by s.color_id) as colorids,
listagg(s.color_name, ',') within group(order by s.color_id) as colornames
from product p
left join (select distinct product_id, color_id, color_name from sku) s
on p.product_id = s.product_id
group by p.product_id
答案 2 :(得分:0)
嗨,这可能也有效。
select product_id,
listagg(color_id,',') within group(order by color_names) as color_ids,
listagg(color_names,',') within group (order by color_names) color_names
from sku
group by product_id;