表頭の複雑な集計
これは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;
このように、
ちなみに、
