用单值和求和替换值集

时间:2015-07-29 14:20:11

标签: sql postgresql

我有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;

是否有智能解决方案?

2 个答案:

答案 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名称将被解释为   输入列名称而不是输出列名称。