给出以下示例数据:
select 'Ada' name, 'Apple' fruit, 2 score union all
select 'Ada', 'Apple', 10 union all
select 'Ada', 'Banana', 8 union all
select 'Ada', 'Cherry', 8 union all
select 'Bob', 'Apple', 5
我想提出一个查询,将数据汇总到
name | fruit | score
-----+---------------+------
Ada | Apple | 10
Ada | Banana,Cherry | 8
Bob | Apple | 5
即如果水果和水果的分数相同,则按名称和水果组合;如果水果和水果的分数相同,则按最高分数
我可以通过
实现select name, string_agg(fruit, ','), score from (
select name, fruit, max(score) score from (
select 'Ada' name, 'Apple' fruit, 2 score union all
select 'Ada', 'Apple', 10 union all
select 'Ada', 'Banana', 8 union all
select 'Ada', 'Cherry', 8 union all
select 'Bob', 'Apple', 5
) data
group by name, fruit
) data
group by name, score
有没有一种更简单的方法可以在一个选择中而不是两个选择中编写查询?
如果您可以解释为什么不能一次选择就写出来,那么“否”是可以接受的答案。
答案 0 :(得分:2)
据我所知,这不可能一步完成,因为您必须使用两种不同的分组-一种获得每个名称和水果的最高分,另一种分组用于string_agg
,这是基于第一个查询的汇总。
话虽如此,但可以使用通用表表达式以更具可读性的方式编写它:
WITH cte AS
(
SELECT name, fruit, max(score) As score
FROM (
SELECT 'Ada' name, 'Apple' fruit, 2 score UNION ALL
SELECT 'Ada' name, 'Apple' fruit, 2 score UNION ALL
SELECT 'Ada', 'Apple', 10 UNION ALL
SELECT 'Ada', 'Banana', 8 UNION ALL
SELECT 'Ada', 'Cherry', 8 UNION ALL
SELECT 'Bob', 'Apple', 5
) data
GROUP BY name, fruit
)
SELECT name, STRING_AGG(fruit, ','), score
FROM cte
GROUP BY name, score