2017-05-10 10 views
0

私は、異なる「グループ化」に従って値を合計/計算しようとしていますが、単一のクエリでそれを行う方法を理解することはできません。複数の「グループ」を1つのクエリに結合しますか?

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

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 
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 | 
+------+----------+----------+------------+ 

最初のクエリは、すべての名前を持っていない場合、次にs left joinからfull joinに、coalesce(a.name,b.name) as nameを使用してください。

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

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; 
0

まず、私はYと言うだろう私たちのソリューションはおそらく、テーブル構造を考えれば、それを行う最も簡単な方法です。

第2に、別のテーブル構造が必要であることをお勧めします。 「名前」は、異なる列のテーブルの周りに散らばってはいけません。索引付けされたフィールドである必要があります。

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); 

これはあまり人が読めるですが、リレーショナルデータベースにうまく機能:私はこのようなテーブルを試してみました。

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 
関連する問題