PostgreSQL - 将第一行显示为其他行的总和

And*_*ius 9 sql postgresql

有没有办法让第一行与其他行不同,所以它会显示相应列的总和?

例如:

      fruits|a|b|c
       total|3|4|6
      apples|1|2|3
     bananas|1|1|2
     oranges|1|1|1
Run Code Online (Sandbox Code Playgroud)

有可能进行这样的查询,或者它是否违反了sql的逻辑?它会是这样的(暂时忽略第一行):

SELECT fruits, sum(a), sum(b), sum(c)
FROM basket
Run Code Online (Sandbox Code Playgroud)

所以第一行会有所不同.它会显示字代替果实名 '总',并且将显示一个(1 + 1 + 1 = 3)中,b的总和(2 + 1 + 1 = 4)和C(3 + 2 + 1 = 6) .有可能这样做吗?谢谢

小智 22

您可以使用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);
Run Code Online (Sandbox Code Playgroud)

查询:

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
Run Code Online (Sandbox Code Playgroud)

结果:

|  FRUITS | A | B | C |
-----------------------
| bananas | 1 | 1 | 2 |
| oranges | 1 | 1 | 1 |
|  apples | 1 | 2 | 3 |
|   total | 3 | 4 | 6 |
Run Code Online (Sandbox Code Playgroud)

SQL小提琴在这里


Sco*_*icz 9

现在可以在Postgres的9.5版本中实现:

PostgreSQL 9.5 Schema

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);
Run Code Online (Sandbox Code Playgroud)

询问

SELECT coalesce(fruits,'total'), sum(a) a, sum(b) b, sum(c) c
FROM basket
GROUP BY ROLLUP((fruits))
Run Code Online (Sandbox Code Playgroud)

结果

 fruits  | a | b | c
---------+---+---+---
 apples  | 1 | 2 | 3
 bananas | 1 | 1 | 2
 oranges | 1 | 1 | 1
 total   | 3 | 4 | 6
Run Code Online (Sandbox Code Playgroud)

ROLLUP相当于使用表达式GROUPING SETS:

SELECT fruits, sum(a) a, sum(b) b, sum(c) c
FROM basket
GROUP BY GROUPING SETS (fruits, ())
Run Code Online (Sandbox Code Playgroud)

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


edz*_*dze 6

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
Run Code Online (Sandbox Code Playgroud)