導入
orders を見ても、そこにあるのは user_id という番号だけ。「これは誰の注文?」を知るには users を見に行く必要があります。この2つの表を、対応する行どうしで横につなげるのが JOIN です。
説明
JOIN は「つなぐ相手の表」を書き、ON で「どの列とどの列が一致したらつなぐか」を指定します。ここでは orders.user_id と users.id が同じ行どうしを結びます。
flowchart LR
subgraph O["orders"]
O1["user_id = 1 / 注文1"]
O2["user_id = 2 / 注文3"]
end
subgraph U["users"]
U1["id = 1 / 佐藤"]
U2["id = 2 / 鈴木"]
end
O1 -->|"ON o.user_id = u.id"| U1
O2 -->|"ON o.user_id = u.id"| U2
U1 --> R["結果: 佐藤 / 注文1<br/>鈴木 / 注文3 …"]
U2 --> R
列名は テーブル名.列名 の形で書くと、どちらの表の列か明確になります。テーブル名が長いと大変なので、AS で短い**別名(エイリアス)**を付けるのが一般的です(orders AS o、users AS u)。
SELECT u.name, o.id, o.ordered_at
FROM orders AS o
JOIN users AS u ON o.user_id = u.id;
これで「注文に会員名がくっついた表」が得られます。ただの JOIN(正式には INNER JOIN/内部結合)は、「両方の表で一致する行だけ」を返します。相手の見つからない行は結果に出ません。
JOIN は集計とも組み合わせられます。「会員ごとの注文件数」はこう書けます。
SELECT u.name, COUNT(*) AS 注文数
FROM orders AS o
JOIN users AS u ON o.user_id = u.id
GROUP BY u.name;
やってみよう
初期表示のクエリを実行して、各注文に会員名が並ぶことを確認しましょう。次に、categories と products を JOIN して「商品にカテゴリ名を並べる」ことに挑戦してみてください(SELECT p.name, c.name FROM products AS p JOIN categories AS c ON p.category_id = c.id;)。
演習
JOIN を使って、**各注文の「会員名(users.name)」と「注文日(orders.ordered_at)」**を並べて取り出してください。
ヒント1を見る
orders と users を ON o.user_id = u.id でつなぎ、u.name と o.ordered_at を選びます。
ヒント2を見る
SELECT u.name, o.ordered_at FROM orders AS o JOIN users AS u ON o.user_id = u.id;