SQLの基礎について復習しています。
今回はgroup byやorder byを使った、条件を指定したテーブルの並べ替えてのデータ取得に加え、HAVING句を使った条件指定について学んでいきます。
課題内容
- 発売年毎の楽曲数を取得しなさい。
- 楽曲数は2つ以上のデータのみを抽出しなさい。
- 楽曲数は降順に並び替えなさい。
- 出力する項目はrelease_year(発売年)とsongs_num(楽曲数)とする。
# songsテーブル
+------+------------+--------------+---------------+
| id | name | release_year | total_minutes |
+------+------------+--------------+---------------+
| 1 | songs1 | 2000 | 3:56 |
| 2 | songs2 | 2007 | 4:07 |
| 3 | songs3 | 1988 | 5:22 |
| 4 | songs4 | 1997 | 4:55 |
| 5 | songs5 | 2016 | 4:13 |
| 6 | songs6 | 1988 | 4:48 |
| 7 | songs7 | 2000 | 4:01 |
| 8 | songs8 | 1992 | 4:20 |
| 9 | songs9 | 1991 | 4:29 |
| 10 | songs10 | 2000 | 4:35 |
+------+------------+--------------+---------------+
自分の回答(間違い)
SELECT release_year, COUNT(*) AS songs_num
FROM songs
GROUP BY release_year
ORDER BY songs_num DESC
HAVING songs_num >= 2
出力結果(エラー)
ERROR: syntax error at or near "HAVING"
LINE 1: ...oks GROUP BY release_year ORDER BY songs_num DESC HAVING boo...
解答のコード
SELECT release_year, COUNT(*) AS songs_num
FROM songs
GROUP BY release_year
HAVING COUNT(*) >= 2
ORDER BY songs_num DESC;
出力結果(正解)
+------+------------+--------------+
| release_year | songs_num |
+------+------------+--------------+
| 2000 | 3 |
| 1988 | 2 |
+------+------------+--------------+
コードの解説
- このコードは「各年で2曲以上発売された楽曲の数を、多い順に表示する」という処理を行うSQL文である。
-
SELECT release_year, COUNT(*) AS songs_num
この部分は、release_year
(発売年)とその年に発売された楽曲の数(COUNT(*)
)を選択するという意味である。 -
AS songs_num
は、発売された楽曲の数をsongs_num
という名前で保存するという意味である。 -
FROM songs
は、songsというテーブル
からデータを取得するという意味である。 -
GROUP BY release_year
この部分は、データをrelease_year
(発売年)ごとにグループ化するという意味である。 -
HAVING COUNT(*) >= 2
この部分は、各release_year
の楽曲数が2以上のものだけを選択するという意味である。 -
ORDER BY songs_num DESC
この部分は、songs_num
(楽曲の数)の降順(多い順)で結果を並べるという意味である。
HAVINGとWHEREの違いを理解する
-
WHERE
との違いは、SQLが実行されるタイミングに違いがある。 - 例えば、この課題の解答例の場合、
HAVING COUNT(*) >= 2
とORDER BY songs_num DESC
のコードを逆にするとエラーとなってデータは取得できない。 - これは、
GROUP BY
が先に実行される仕組みになっているためである。 - SELECT文を使用したSQL文の場合、命令が実行される順番は、、、
①FROM
→②WHERE
→③GROUP BY
→④HAVING
→⑤SELECT
→⑥ORDER BY
となっている。 - 今回の場合、
GROUP BY
句を使ってグループ化しているため、HAVINGを使う場合は、GROUP BY
句の次に持ってこないとダメ、ということになる。 -
GROUP BY
句を使った場合、WHERE
は、グループ化する前の元データに対しての条件指定することになる。 -
GROUP BY
句を使った場合、HAVING
はグループ化した後の加工後データに対しての条件指定をすることになる。
参考サイト