事情是因為這樣了——我需要按2個次元來分組,求出按這2個次元分組的總數情況(count),但同時也需要在這2個次元下求出按不同條件得出的總數,這些不同條件下分别得出的總數相加的和即為不加上條件的情況下的總數。比如:
假設有一張tablename表格,資料結構如下:
字段: id A B condition2
SELECT
COUNT(1) cnt,
A,
B
FROM
tablename
WHERE 1 = 1
AND B LIKE '201602%'
GROUP BY A,
B
ORDER BY A,
B
這是從tablename表中取出一定條件下按A,B分組的總數情況,假設現在我B的條件不變,需要統計根據condition字段(假設condition是一個枚舉值的字段,即它的取值為1,2,3三種可能)來變化的總數,那麼我需要分别寫幾個sql:
SELECT
COUNT(1) cnt,
A,
B
FROM
tablename
WHERE 1 = 1
AND B LIKE '201602%'
AND condition = '1'
GROUP BY A,
B
ORDER BY A,
B
這裡的count統計條件是AND condition = '1' 還有可能是AND condition = '2'和AND condition = '3',然後這些不同的condition取值條件下的count統計取值分别為cnt1 cnt2 cnt3 則cnt1 + cnt2 + cnt3 = cnt(不加上condition過濾條件時的統計值).
問題來了,如何在一條記錄裡同時把cnt和cnt1-cnt3都展示出來呢?
之前我是先求出cnt的集合,再循環每一條記錄,根據每條記錄的A,B和condition取值去得到該條記錄加上condition後對應的cnt,但後來發現這是十分不可取的,因為每條記錄都得連接配接資料庫去執行sql查詢,顯得效率低下。。
後來發現在這種情形下,case when then else end就可以起作用,但十分神奇的是,他竟然也能夠和count函數結合起來:
ELECT
COUNT(1) cnt,
COUNT(
CASE
WHEN condition = '1'
THEN 1
ELSE NULL
END
) cnt1,
COUNT(
CASE
WHEN condition = '2'
THEN 1
ELSE NULL
END
) cnt2,
COUNT(
CASE
WHEN condition = '3'
THEN 1
ELSE NULL
END
) cnt3,
A,
B
FROM
tablename
WHERE 1 = 1
AND B LIKE '201602%'
GROUP BY A,
B
ORDER BY A,
B
這裡需要注意count函數裡面包圍case when then else end的用法;還有一點需注意的是:count(null)得到的是0,這表明不符合目前條件下,走的是else null 這時候count(null)就為0啦~~,即不在目前條件下統計,否則count(1)就是統計了!!!
很神奇吧!看看結果:
多仔細幾條記錄,會發現每條記錄都同時包含了cnt 和cnt1-cnt3,并且cnt = cnt1 + cnt2 + cnt3. 這說明我們這句sql求出的記錄是正确的!
補充,同理的還有sum函數包圍case when then else end,需注意不滿足目前條件走else分支時,是要這樣寫的,sum(case when condition='1' then val else 0 end),即sum(0)才是0.
小結下:sum(0) = 0 , count(null) = 0. 在遇到這種情形的統計時,可考慮case when then else end語句哦。比如需要在一條記錄裡「同時」統計出總人數,男生人數和女生人數~~~
- 大小: 9 KB
- 檢視圖檔附件