请注意,这是不与评论中引用的问题重复,因为这需要CTE。
如何创建递归的公用表表达式,它结合了分组数据(如string_agg()
或group_concat()
)?
例如,我有一个简单的数据集,如下所示:
┌──────┬──────────┐
│ code │ category │
╞══════╪══════════╡
│ 1 │ A │
├──────┼──────────┤
│ 1 │ B │
├──────┼──────────┤
│ 2 │ A │
├──────┼──────────┤
│ 3 │ B │
├──────┼──────────┤
│ 4 │ B │
├──────┼──────────┤
│ 4 │ C │
├──────┼──────────┤
│ 4 │ D │
├──────┼──────────┤
│ 5 │ B │
└──────┴──────────┘
我想生成一个结果集,按类别按组合组合类别:
┌──────┬──────────┐
│ code │ category │
╞══════╪══════════╡
│ 1 │ A,B │
├──────┼──────────┤
│ 2 │ A │
├──────┼──────────┤
│ 3 │ B │
├──────┼──────────┤
│ 4 │ B,C,D │
├──────┼──────────┤
│ 5 │ B │
└──────┴──────────┘
我认为答案可能是通用的,但我特别感兴趣的是为PostgreSQL,SQLite和SQL Server寻找解决方案。
答案 0 :(得分:0)
有足够的推力,猪飞得很好。但是,这不一定是个好主意 - RFC 1925
首先,获取所有不同的code
值。
然后确定每个category
的第一个(最小)code
值。
然后,在递归中,为每个category
获取下一个更大的code
值。
结果包含为每个code
执行最新步骤的所有行:
WITH RECURSIVE OinkOink(code, category, combined, step) AS (
SELECT code,
(SELECT MIN(MyTable.category)
FROM MyTable
WHERE MyTable.code = DistinctCodes.code),
(SELECT MIN(MyTable.category)
FROM MyTable
WHERE MyTable.code = DistinctCodes.code),
1
FROM (SELECT DISTINCT code
FROM MyTable) AS DistinctCodes
UNION ALL
SELECT code,
(SELECT MIN(MyTable.category)
FROM MyTable
WHERE MyTable.code = OinkOink.code
AND MyTable.category > OinkOink.category),
combined || ',' ||
(SELECT MIN(MyTable.category)
FROM MyTable
WHERE MyTable.code = OinkOink.code
AND MyTable.category > OinkOink.category),
step + 1
FROM OinkOink
WHERE EXISTS (SELECT *
FROM MyTable
WHERE MyTable.code = OinkOink.code
AND MyTable.category > OinkOink.category)
)
SELECT code, combined
FROM OinkOink
JOIN (SELECT code,
MAX(step) AS step
FROM OinkOink
GROUP BY code) AS LargestSteps
USING (code, step)
ORDER BY code;