有没有办法让第一行与其他行不同,所以它会显示相应列的总和?
例如:
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)的总和。有可能这样做吗?感谢
答案 0 :(得分: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);
<强>查询强>:
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
答案 1 :(得分:8)
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子句中的解释方式相同。
答案 2 :(得分:5)
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