我有a table如下:
id group1 group2 is_bar amount
1 a bar1 true 100
2 a bar2 true 200
3 a baz false 150
4 a baz false 250
5 b bar1 true 50
每次is_bar
为真,我都要替换group2
中的值并将amount
的总和替换为:
group1 group2 amount
a bar 300
a baz 400
b bar 50
我目前使用子查询执行此操作,然后按表中的每个其他列进行分组!但这对我来说似乎有点小便:
SELECT group1, group2, sum(amount) FROM
(
SELECT group1,
CASE WHEN is_bar THEN 'bar' ELSE group2 END as group2,
amount
FROM foo
) new_foo
GROUP BY group1, group2
ORDER BY group1, group2;
是否有智能解决方案?
答案 0 :(得分:2)
我相信这应该有效:
SELECT
group1
, CASE WHEN is_bar THEN 'bar' ELSE group2 END as group2
, SUM(AMOUNT)
FROM foo
GROUP BY group1, CASE WHEN is_bar THEN 'bar' ELSE group2 END
正如@Patrick在评论中提到的,您可以使用GROUP BY
替换GROUP BY 1, 2
中非常长的条件。
这将自动引用SELECT
语句中的第1列和第2列(第一个和第二个),查询将具有相同的输出。但是,如果您添加不同的列作为第一列,则必须通过更改或添加表示第一列的数字/条件来确保GROUP BY
仍然按预期工作。
答案 1 :(得分:1)
事实证明,在Postgresql中你可以 GROUP BY
一个别名列,如this part of the docs中所述:
在严格的SQL中,GROUP BY只能按源表的列进行分组 但PostgreSQL对此进行了扩展,以允许GROUP BY按列分组 在选择列表中。按值表达式分组而不是简单 列名也是允许的。
此SQL Fiddle显示了该行动:
SELECT
group1,
CASE WHEN is_bar THEN 'bar' ELSE group2 END group2_grouped,
SUM(AMOUNT)
FROM foo
GROUP BY group1, group2_grouped
当您尝试将CASE
语句的别名与列名称相同时,会出现问题,因为Postgresql将GROUP BY
原始列而不是别名。这在the docs中提到:
如果含糊不清,GROUP BY名称将被解释为 输入列名称而不是输出列名称。