20201111_アウトプット①(SQL複雑な条件・評価順序)
学んだこと 2時間20分
複雑な条件で検索してみよう(SQL)
SELECT CONCAT(last_name, first_name) "名前", COUNT(*) "コマ数" FROM shifts s JOIN users u ON s.user_id = u.id WHERE date = "2020-07-01" GROUP BY user_id
上記を見て、疑問に感じたこと
なぜ、SELECTで苗字と名前の要素を取得しているはずなのに、その後、user_idとidを繋げられるのか?プログラミング言語って上から読み込まれるんじゃないの?と疑問に感じた。
調べたら、SQLには処理順序があることがわかった!😲
順序 | 句 |
---|---|
1 | FROM |
2 | ON |
3 | JOIN |
4 | WHERE |
5 | GROUP BY |
6 | WITH CUBE または WITH ROLLUP |
7 | HAVING |
8 | SELECT |
9 | DISTINCT |
10 | ORDER BY |
11 | TOP |
なるほどね!
そうすると、先ほどの命令文は、
SELECT CONCAT(last_name, first_name) "名前", COUNT(*) "コマ数" FROM shifts s JOIN users u ON s.user_id = u.id WHERE date = "2020-07-01" GROUP BY user_id
①shiftsテーブルから取ってきますFROM
②user_idとidをくっつけますON
③くっつけるもう一つのデータはusersテーブルねJOIN
④日付は2020-07-01を指定WHERE
⑤user_idごとにグループ化しますGROUP BY
⑥苗字と名前を取得してきて、くっつけますSELECT
・CONCAT
⑦”コマ数”として、⑤の集計結果を取得してきますSELECT
・COUNT
になるので、とてもすっきりした!!✨
ここでさらに理解が深まったこと。
読み込まれる順序が決まっているということは、別名をつけるタイミングに気をつけないとエラーが出る。
どういうことかというと、上記で言えば、shifts
テーブルをs
っていう別名をつけることをしているのだが、読み込まれる順番が遅い句に後から別名をつけた場合にはそれより前の句には適用されておらずエラーになることが起きる。
この記事もわかりやすかったです。
それぞれの句 覚書
JOIN / 一致したカラムの値に関連づけて他テーブルのレコードを結合できる
FROM句の後に記述する
結合元となるカラムを
ON
の後に=
を用いて指定する。
FROM 《テーブル名1》 JOIN 《テーブル名2》 ON 《テーブル名1.カラム名1》 = 《テーブル名2.カラム名2》
CONCAT / 複数の文字列を連結できる
- 連結する文字列の中に「NULL」があると結果は「NULL」になってしまうので気をつけよう
CONCAT(文字列1, 文字列2, ……)
GROUP BY / データをグループ化する
GROUP BY カラム名
COUNT / グループ化したデータの総量をカウントできる
- カラムの値が「NULL」だとエラーになるので気をつけよう
SELECT COUNT(カラム名)
- ただし、以下のように記述すると「行の値が全てNULL」であるレコードも含めて、行数を取得できる。
SELECT COUNT(*)
サブクエリ&入れ子構造でデータを取得
サブクエリとは?
ある検索結果を使用して、別のSQL文を実行する仕組み。
入れ子構造とは?
以下のように()
の中に、別のリストをいれること。
NOT IN
なので、2020-07-01
のシフトに入っていない人、という意味になる。
SELECT * FROM users WHERE id NOT IN ( SELECT user_id FROM shifts WHERE date = "2020-07-01" )