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には処理順序があることがわかった!😲

docs.microsoft.com

順序
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
⑥苗字と名前を取得してきて、くっつけますSELECTCONCAT
⑦”コマ数”として、⑤の集計結果を取得してきますSELECTCOUNT
になるので、とてもすっきりした!!✨


ここでさらに理解が深まったこと。
読み込まれる順序が決まっているということは、別名をつけるタイミングに気をつけないとエラーが出る。
どういうことかというと、上記で言えば、shiftsテーブルをsっていう別名をつけることをしているのだが、読み込まれる順番が遅い句に後から別名をつけた場合にはそれより前の句には適用されておらずエラーになることが起きる。
この記事もわかりやすかったです。

qiita.com

それぞれの句 覚書

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"
)