我正在尝试根据不同的“分组依据”对值进行求和/计算,但我无法弄清楚如何在单个查询中执行此操作。
CREATE TABLE test(
col1 text,
col2 text,
col3 int
);
INSERT INTO test VALUES('A', '', 10);
INSERT INTO test VALUES('A', 'A', 15);
INSERT INTO test VALUES( '', 'A', 100);
INSERT INTO test VALUES('B', 'C', 1);
INSERT INTO test VALUES('C', '', 33);
我已经想出如何部分得到我正在寻找的东西:
--(this might not be the "correct" way, just my experiments)
SELECT col1 AS name, sum(col3) as col1_sum FROM test GROUP BY col1;
SELECT col2 AS name, sum(col3) as col2_sum FROM test GROUP BY col2;
除了上述内容,我想计算差异b_sum - a_sum,所以完整的查询结果将是:
name col1_sum col2_sum difference
---- -------- -------- ----------
A 25 115 90
B 1 (empty) -1
C 33 1 -32
(empty) 100 43 -57
如何获得上述输出的任何想法..?谢谢!
答案 0 :(得分:2)
我在聚合后想full outer join
:
select coalesce(t1.name, t2.name) as name, t1.col1_num, t2.col2_sum,
coalesce(t2.col2_sum, 0) - coalesce(t1.col1_sum, 0) as diff
from (select col1 as name, sum(col3) as col1_sum
from ttest
group by col1
) t1 full outer join
(select col2 as name, sum(col3) as col2_sum
from ttest
group by col2
) t2
on t1.name = t2.name;
答案 1 :(得分:1)
使用UNION ALL
合并结果,然后减去这些值。
select name,max(col1_sum),max(col2_sum),coalesce(max(col2_sum),0)-coalesce(max(col1_sum),0)
from (
SELECT col1 AS name, sum(col3) as col1_sum,null col2_sum
FROM test
GROUP BY col1
UNION ALL
SELECT col2, null, sum(col3)
FROM test
GROUP BY col2
) t
GROUP BY name
答案 2 :(得分:1)
with t as (
select col1, col2, sum(col3), grouping((col1),(col2))
from test
group by grouping sets ((col1),(col2))
)
select
coalesce(t1.col1, t1.col2) as col,
t1.sum as col1_sum,
t2.sum as col2_sum,
coalesce(t2.sum, 0) - coalesce(t1.sum, 0) as difference
from t t1 full join t t2 on t1.col1 = t2.col2
where t1.col1 <> '' or t2.col2 <> '' or (t1.col1 = '' and t2.col2 = '')
;
col | col1_sum | col2_sum | difference
-----+----------+----------+------------
| 100 | 43 | -57
A | 25 | 115 | 90
B | 1 | | -1
C | 33 | 1 | -32
答案 3 :(得分:0)
使用公用表表达式:
;with a as (
SELECT
col1 AS name
, sum(col3) as col1_sum
FROM test
GROUP BY col1
)
, b as (
SELECT
col2 AS name
, sum(col3) as col2_sum
FROM test
GROUP BY col2
)
select
a.name
, a.col1_sum
, b.col2_sum
, coalesce(b.col2_sum,0) - coalesce(a.col1_sum,0) as difference
from a
left join b
on a.name = b.name
order by a.name
rextester演示:http://rextester.com/YROWT76204
返回:
+------+----------+----------+------------+
| name | col1_sum | col2_sum | difference |
+------+----------+----------+------------+
| | 100 | 43 | -57 |
| A | 25 | 115 | 90 |
| B | 1 | NULL | -1 |
| C | 33 | 1 | -32 |
+------+----------+----------+------------+
如果第一个查询没有所有名称,请从left join
切换到full join
并使用coalesce(a.name,b.name) as name
。
答案 4 :(得分:0)
select a.name, col1_sum, col2_sum , coalesce(col2_sum,0) - coalesce(col1_sum,0) as diff from (SELECT case when col1 is null then '(empty)' else col1 end AS name, sum(col3) as col1_sum FROM test GROUP BY col1) a full outer join (SELECT case when col2 is null then '(empty)' else col2 end AS name, sum(col3) as col2_sum FROM test GROUP BY col2) b on a.name = b.name order by a.name;
name | col1_sum | col2_sum | diff :--- | -------: | -------: | ---: | 100 | 43 | -57 A | 25 | 115 | 90 B | 1 | null | -1 C | 33 | 1 | -32
dbfiddle here
答案 5 :(得分:0)
首先,我要说你的解决方案可能是给定表结构的最简单方法。
其次,我建议你需要一个不同的表结构。 &#34;名称&#34;不应该分散在不同列的表中 - 它需要是一个索引字段。我试试这样的表:
CREATE TABLE test(
aInstance int,
aName text,
col_nam int,
col_val int
);
INSERT INTO test VALUES(1,'A',1, 10);
INSERT INTO test VALUES(2,'A',1, 15);
INSERT INTO test VALUES(2,'A',2, 15);
INSERT INTO test VALUES(3,'A',2, 100);
INSERT INTO test VALUES(3,'B',1, 1);
INSERT INTO test VALUES(3,'C',2, 1);
INSERT INTO test VALUES(4,'C',2, 33);
这不像人类可读,但在关系数据库中效果更好。