【问题标题】:PostgreSQL - making first row show as total of other rowsPostgreSQL - 使第一行显示为其他行的总数
【发布时间】:2012-12-12 12:32:43
【问题描述】:

有什么方法可以让第一行与其他行不同,这样它就会显示相应列的总和?

例如:

      fruits|a|b|c
       total|3|4|6
      apples|1|2|3
     bananas|1|1|2
     oranges|1|1|1

是否可以进行这样的查询或违反sql的逻辑? 应该是这样的(暂时忽略第一行):

SELECT fruits, sum(a), sum(b), sum(c)
FROM basket

所以第一行会有所不同。它将显示单词“total”而不是水果名称,并显示 a (1+1+1=3)、b (2+1+1=4) 和 c (3+2+1=6) 的总和.有可能这样做吗?谢谢

【问题讨论】:

标签: sql postgresql


【解决方案1】:

您可以避免使用 CTE 对表进行第二次全扫描:

PostgreSQL 9.2 架构

create table basket(fruits text, a integer, b integer, c integer);
insert into basket(fruits, a, b, c) values('apples', 1, 1, 1),
                                          ('apples', 0, 1, 2),
                                          ('bananas', 1, 1, 2),
                                          ('oranges', 1, 1, 1);

查询

with w as ( select fruits, sum(a) a, sum(b) b, sum(c) c
            from basket
            group by fruits )
select * from w union all select 'total', sum(a), sum(b), sum(c) from w

结果

|  FRUITS | A | B | C |
-----------------------
| bananas | 1 | 1 | 2 |
| oranges | 1 | 1 | 1 |
|  apples | 1 | 2 | 3 |
|   total | 3 | 4 | 6 |

SQL 小提琴here

【讨论】:

  • 谢谢。这样就更好了。
  • 谢谢。我喜欢 postgres,但这个问题让我希望 rollup 这是一种更自然的方式。
【解决方案2】:

This is now possible in version 9.5 of Postgres:

PostgreSQL 9.5 架构

CREATE TABLE basket(fruits text, a integer, b integer, c integer);
CREATE TABLE
INSERT INTO basket(fruits, a, b, c) values('apples', 1, 1, 1),
                                      ('apples', 0, 1, 2),
                                      ('bananas', 1, 1, 2),
                                      ('oranges', 1, 1, 1);

查询

SELECT coalesce(fruits,'total'), sum(a) a, sum(b) b, sum(c) c
FROM basket
GROUP BY ROLLUP((fruits))

结果

 fruits  | a | b | c
---------+---+---+---
 apples  | 1 | 2 | 3
 bananas | 1 | 1 | 2
 oranges | 1 | 1 | 1
 total   | 3 | 4 | 6

这个ROLLUP 等价于使用带有GROUPING SETS 的表达式:

SELECT fruits, sum(a) a, sum(b) b, sum(c) c
FROM basket
GROUP BY GROUPING SETS (fruits, ())

GROUPING SETS 中的每个子列表的解释方式与直接在 GROUP BY 子句中的方式相同。

【讨论】:

    【解决方案3】:
    SELECT 'total' AS fruits, sum(a), sum(b), sum(c) FROM basket
    UNION ALL
    SELECT fruits, sum(a), sum(b), sum(c) FROM basket GROUP BY fruits
    

    【讨论】:

      猜你喜欢
      • 2015-01-09
      • 2018-07-08
      • 2022-08-13
      • 2016-08-16
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 2018-11-20
      相关资源
      最近更新 更多