はじめに
SQLという言語の大きな特徴として、
しかし一方で、
本章では、
複数行を1行にまとめる
SQLには、
- COUNT
- SUM
- AVG
- MAX
- MIN
たぶん、
この効果を体感するために、
id | data_ | data_ | data_ | data_ | data_ | data_ | data_ |
---|---|---|---|---|---|---|---|
Jim | A | 100 | 10 | 34 | 346 | 54 | |
Jim | B | 45 | 2 | 167 | 77 | 90 | 157 |
Jim | C | 3 | 687 | 1355 | 324 | 457 | |
Ken | A | 78 | 5 | 724 | 457 | 1 | |
Ken | B | 123 | 12 | 178 | 346 | 85 | 235 |
Ken | C | 45 | 23 | 46 | 687 | 33 | |
Beth | A | 75 | 0 | 190 | 25 | 356 | |
Beth | B | 435 | 0 | 183 | 4 | 325 | |
Beth | C | 96 | 128 | 0 | 0 | 12 |
CSVや固定長などのフラットファイルをそのままテーブルに写し取った形の、
さて、
すると、
SELECT id, data_1, data_2
FROM NonAggTbl
WHERE id = 'Jim'
AND data_type = 'A';
id data_1 data_2 ---- ------- ------- Jim 100 10
SELECT id, data_3, data_4, data_5
FROM NonAggTbl
WHERE id = 'Jim'
AND data_type = 'B';
id data_3 data_4 data_5 ---- ------ ------ ------ Jim 167 77 90
SELECT id, data_6
FROM NonAggTbl
WHERE id = 'Jim'
AND data_type = 'C';
id data_6 ---- ------ Jim 457
これは、
したがって本当は、
id | data_ | data_ | data_ | data_ | data_ | data_ |
---|---|---|---|---|---|---|
Jim | 100 | 10 | 167 | 77 | 90 | 457 |
Ken | 78 | 5 | 178 | 346 | 85 | 33 |
Beth | 75 | 0 | 183 | 4 | 12 |
先ほどのNonAggTblと比べれば、
では問題です。NonAggTblからAggTblへの変換を行うSQLを考えましょう。考え方としては、
SELECT id,
CASE WHEN data_type = 'A' THEN data_1 ELSE NULL END AS data_1,
CASE WHEN data_type = 'A' THEN data_2 ELSE NULL END AS data_2,
CASE WHEN data_type = 'B' THEN data_3 ELSE NULL END AS data_3,
CASE WHEN data_type = 'B' THEN data_4 ELSE NULL END AS data_4,
CASE WHEN data_type = 'B' THEN data_5 ELSE NULL END AS data_5,
CASE WHEN data_type = 'C' THEN data_6 ELSE NULL END AS data_6
FROM NonAggTbl
GROUP BY id;
このクエリは、 に限定されるからです。いま、 しかしこれは、 MAX関数を使ったのは、 いかがでしょう。まさに
SELECT id,
MAX(CASE WHEN data_type = 'A' THEN data_1 ELSE NULL END) AS data_1,
MAX(CASE WHEN data_type = 'A' THEN data_2 ELSE NULL END) AS data_2,
MAX(CASE WHEN data_type = 'B' THEN data_3 ELSE NULL END) AS data_3,
MAX(CASE WHEN data_type = 'B' THEN data_4 ELSE NULL END) AS data_4,
MAX(CASE WHEN data_type = 'B' THEN data_5 ELSE NULL END) AS data_5,
MAX(CASE WHEN data_type = 'C' THEN data_6 ELSE NULL END) AS data_6
FROM NonAggTbl
GROUP BY id;
id data_1 data_2 data_3 data_4 data_5 data_6
------ ------ ------ ------ ------ ------ ------
Jim 100 10 167 77 90 457
Ken 78 5 178 346 85 33
Beth 75 0 183 NULL 4 12