表頭の複雑な集計
これはCASE式の使い方の中で最も使い勝手がよく応用範囲の広い技術なので、
emp_ | dept | sex | age | salary |
---|---|---|---|---|
001 | 製造 | 男 | 32 | 30 |
002 | 製造 | 男 | 30 | 29 |
003 | 製造 | 女 | 23 | 19 |
004 | 会計 | 男 | 45 | 35 |
005 | 会計 | 男 | 50 | 45 |
006 | 営業 | 女 | 40 | 50 |
007 | 営業 | 女 | 42 | 40 |
008 | 営業 | 男 | 52 | 38 |
009 | 営業 | 男 | 34 | 28 |
010 | 営業 | 女 | 41 | 25 |
011 | 人事 | 男 | 29 | 25 |
012 | 人事 | 女 | 36 | 29 |
ここからいろいろな組み合わせのクロス表を作ってみましょう。こういう要件は実務の中でも頻繁に発生すると思いますが、
「第1回 ウォーミングアップ」
若手 | ベテラン | |||
---|---|---|---|---|
男 | 女 | 男 | 女 | |
製造 | 1 | 1 | 1 | 0 |
会計 | 0 | 0 | 2 | 0 |
営業 | 0 | 0 | 2 | 3 |
人事 | 1 | 0 | 0 | 1 |
SELECT dept,
SUM(CASE WHEN age <= 30 AND sex = '男' THEN 1 ELSE 0 END) AS "若手(男)",
SUM(CASE WHEN age <= 30 AND sex = '女' THEN 1 ELSE 0 END) AS "若手(女)",
SUM(CASE WHEN age >= 31 AND sex = '男' THEN 1 ELSE 0 END) AS "ベテラン(男)",
SUM(CASE WHEN age >= 31 AND sex = '女' THEN 1 ELSE 0 END) AS "ベテラン(女)"
FROM Employees
GROUP BY dept;
CASE式の戻り値を0/
では、
合計 | 若手 | ベテラン | |||||
---|---|---|---|---|---|---|---|
計 | 男 | 女 | 計 | 男 | 女 | ||
製造 | 3 | 2 | 1 | 1 | 1 | 1 | 0 |
会計 | 2 | 0 | 0 | 0 | 2 | 2 | 0 |
営業 | 5 | 0 | 0 | 0 | 5 | 2 | 3 |
人事 | 2 | 1 | 1 | 0 | 1 | 0 | 1 |
これも、
SELECT dept,
COUNT(*),
SUM(CASE WHEN age <= 30 THEN 1 ELSE 0 END) AS "若手(計)",
SUM(CASE WHEN age <= 30 AND sex = '男' THEN 1 ELSE 0 END) AS "若手(男)",
SUM(CASE WHEN age <= 30 AND sex = '女' THEN 1 ELSE 0 END) AS "若手(女)",
SUM(CASE WHEN age >= 31 THEN 1 ELSE 0 END) AS "ベテラン(計)",
SUM(CASE WHEN age >= 31 AND sex = '男' THEN 1 ELSE 0 END) AS "ベテラン(男)",
SUM(CASE WHEN age >= 31 AND sex = '女' THEN 1 ELSE 0 END) AS "ベテラン(女)"
FROM Employees
GROUP BY dept;
合計列のCOUNT(*)はSUM(1)としても同じです。あるいはそう書いたほうが
また、
SELECT dept,
COUNT(*),
COUNT(CASE WHEN age <= 30 THEN 1 ELSE NULL END) AS "若手(計)",
COUNT(CASE WHEN age <= 30 AND sex = '男' THEN 1 ELSE NULL END) AS "若手(男)",
COUNT(CASE WHEN age <= 30 AND sex = '女' THEN 1 ELSE NULL END) AS "若手(女)",
COUNT(CASE WHEN age >= 31 THEN 1 ELSE NULL END) AS "ベテラン(計)",
COUNT(CASE WHEN age >= 31 AND sex = '男' THEN 1 ELSE NULL END) AS "ベテラン(男)",
COUNT(CASE WHEN age >= 31 AND sex = '女' THEN 1 ELSE NULL END) AS "ベテラン(女)"
FROM Employees
GROUP BY dept;
このように、
ちなみに、