[英]SQL Aggregation with SUM, GROUP BY and JOIN (many-to-many)
這是表格布局的示例:
TABLE_A: TABLE_B: TABLE_A_B:
id | a | b | c id | name a_id | b_id
--------------------- --------- -----------
1 | true | X | A 1 | A 1 | 1
2 | true | Z | null 2 | B 1 | 2
3 | false | X | null 3 | C 2 | 2
4 | true | Y | Q 4 | 1
5 | false | null | null 4 | 2
5 | 1
可能的值:
我要實現的目標:
SELECT all rows from TABLE_A
SUM(where a = true),
SUM(where a = false),
SUM(where b = 'X'),
SUM(where b = 'Y'),
SUM(where b = 'Z'),
SUM(where b IS NULL),
and also get the SUMs for all distinct TABLE_A.c values.
and also get the SUMs for all those TABLE_A_B relations.
上面的示例表的結果應如下所示:
aTrue | aFalse | bX | bY | bZ | bNull | cA | cQ | cNull | nameA | nameB | nameC
-------------------------------------------------------------------------------
3 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 3 | 3 | 3 | 0
到目前為止,我所做的是:
SELECT
SUM(CASE WHEN a = true THEN 1 ELSE 0 END) AS aTrue,
SUM(CASE WHEN b = false THEN 1 ELSE 0 END) AS aFalse,
SUM(CASE WHEN b = 'X' THEN 1 ELSE 0 END) AS bX,
...
FROM TABLE_A
我怎么了
選擇TABLE_A.a
和TABLE_A.b
列很容易,因為存在固定數量的可能值。
但是我不知道如何計算TABLE_A.c
的不同值。 基本上同樣的問題對於加盟TABLE_B
, 因為中值的數量TABLE_B
是未知的,可以隨時間而改變。
謝謝你的幫助! :)
column | value | sum
----------------------------
TABLE_A.a | true | 3
TABLE_A.a | false | 2
TABLE_A.b | X | 2
TABLE_A.b | Y | 1
TABLE_A.b | Z | 1
TABLE_A.b | null | 1
TABLE_A.c | A | 1
TABLE_A.c | Q | 1
TABLE_A.c | null | 3
TABLE_B.name | A | 3
TABLE_B.name | B | 3
TABLE_B.name | C | 0
從您最初對行的請求作為模擬樞軸。 通過執行SUM(邏輯條件),如果為true,則基本上返回1,如果為false,則返回0。 因此,由於列“ a”是對還是錯,所以“ a”或NOT“ a”的簡單總和(對於錯誤計數-NOT FALSE = TRUE)。 同樣,您的“ b”列,因此b ='X'= true計為1,否則計為0。
在其他SQL引擎中,您可能將其視為SUM(case / when)。
現在,由於您的表計數不再相互依賴,因此可以將SUM()分為各自的子別名查詢引用(分別對於pre-queryA和pre-queryB使用pqA和pqB)。 由於沒有分組依據,因此它們各自將導致一行。 沒有連接將創建笛卡爾,但由於比例為1:1,因此僅返回所需所有列的單個記錄。
SELECT
pqA.*, pqB.*
from
( SELECT
SUM( ta.a ) aTrue,
SUM( NOT ta.a ) aFalse,
SUM( ta.b = 'X' ) bX,
SUM( ta.b = 'Y' ) bY,
SUM( ta.b = 'Z' ) bZ,
SUM( ta.b is null ) bNULL,
SUM( ta.c = 'A' ) cA,
SUM( ta.c = 'Q' ) cQ,
SUM( ta.c is null ) cNULL,
COUNT( distinct ta.c ) DistC
from
table_a ta ) pqA,
( SELECT
SUM( b.Name = 'A' ) nameA,
SUM( b.Name = 'B' ) nameB,
SUM( b.Name = 'C' ) nameC
from
table_a_b t_ab
join table_b b
ON t_ab.b_id = b.id ) pqB
此選項提供您的第二個(首選)輸出
SELECT
MAX( 'TABLE_A.a ' ) as Basis,
CASE when a then 'true' else 'false' end Value,
COUNT(*) finalCnt
from
TABLE_A
group by
a
UNION ALL
SELECT
MAX( 'TABLE_A.b ' ) as Basis,
b Value,
COUNT(*) finalCnt
from
TABLE_A
group by
b
UNION ALL
SELECT
MAX( 'TABLE_A.c ' ) as Basis,
c Value,
COUNT(*) finalCnt
from
TABLE_A
group by
c
UNION ALL
SELECT
MAX( 'TABLE_B.name ' ) as Basis,
b.Name Value,
COUNT(*) finalCnt
from
table_a_b t_ab
join table_b b
ON t_ab.b_id = b.id
group by
b.Name
我認為您將需要構建動態查詢,因為您不知道表A中C列的可能值。因此,您可以編寫存儲過程,在其中可以在一個變量中使用“ Do WHILE”獲取C列的不同值的列表。您可以構建動態查詢。 如果您需要更多詳細的動態SQL請讓我知道
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.