我有下面的Oracle SQL表,其中product_id
101和103分别在attr1
和attr3
列中具有不同的值。data
| PRODUCT_ID | ATTR1 | ATTR2 | ATTR3 |
|------------|-------|-------|-------|
| 101 | a | x | z |
| 101 | a | x | zzz |
| 101 | aa | x | z |
| 102 | b | y | z |
| 102 | b | y | z |
| 103 | c | z | z |
| 103 | c | z | zz |
我想得到以下输出,其中列出了不同的值及其在列中的计数。output
| PRODUCT_ID | DESCR | VALUE_COUNT |
|------------|------------------|--------------|
| 101 | Issue with attr1 | a(2), aa(1) |
| 101 | Issue with attr3 | z(2), zzz(1) |
| 103 | Issue with attr3 | z(1), zz(1) |
我编写了一个查询来获取一列的结果,但是要为实际数据编写查询需要花费相当大的精力,因为我需要检查20多列的不同值。有什么建议可以让它更有效率吗?query
WITH data AS (
SELECT 101 product_id, 'a' attr1, 'x' attr2, 'z' attr3 FROM dual UNION ALL
SELECT 101 product_id, 'a' attr1, 'x' attr2, 'zzz' attr3 FROM dual UNION ALL
SELECT 101 product_id, 'aa' attr1, 'x' attr2, 'z' attr3 FROM dual UNION ALL
SELECT 102 product_id, 'b' attr1, 'y' attr2, 'z' attr3 FROM dual UNION ALL
SELECT 102 product_id, 'b' attr1, 'y' attr2, 'z' attr3 FROM dual UNION ALL
SELECT 103 product_id, 'c' attr1, 'z' attr2, 'z' attr3 FROM dual UNION ALL
SELECT 103 product_id, 'c' attr1, 'z' attr2, 'zz' attr3 FROM dual
), d1 AS (
SELECT product_id, 'Issue with attr1' descr
FROM data
GROUP BY product_id
HAVING COUNT(DISTINCT attr1) > 1
), d2 AS (
SELECT DISTINCT d1.product_id, d1.descr, data.attr1, COUNT(attr1) OVER (PARTITION BY attr1) cnt
FROM d1
INNER JOIN data
ON d1.product_id = data.product_id
)
SELECT product_id, descr, LISTAGG(attr1 || '(' || cnt || ')', ', ') WITHIN GROUP (ORDER BY product_id) value_count
FROM d2
GROUP BY product_id, descr
;
3条答案
按热度按时间dsekswqp1#
您可以将所有属性反透视到单独的行中,计算每个属性和值的行数,并将其与每个
product_id
的行数进行比较。然后将错误聚合回listagg
。这只需要向
inpivot ... for ...
添加更多列。fiddle
UPD:默认
unpivot removes
nullvalues from output. To include them you need to add
include nulls`。如果向示例数据中添加一行
null
:上述(修改后)查询将返回:
| 产品编号|问题|VALUE_COUNT|
| --------------|--------------|--------------|
| 一百零一|ATTR 1问题|a(2)、aa(1)|
| 一百零一|关于ATTR 3|zz(2),zzz(1)|
| 一百零三|关于ATTR 3|(1)、zz(1)、NULL(1)|
fiddle
rur96b6h2#
尝试先GROUPing,然后围绕它Listagg。就像这样:
xxls0lw83#
如果你没有太多的属性,你可以这样做:
fiddle