SQLでテーブルを結合するとき、JOIN ... ONとJOIN ... USINGのどちらを使うべきか迷うことがあります。
結論からいうと、基本は次の使い分けです。
- ON句: 列名が違う場合、複数条件を使う場合、柔軟に条件を書きたい場合
- USING句: 両方のテーブルに同じ列名があり、その列で等価結合したい場合
この記事では、ONとUSINGの違いを、実際のSQLと結果列の違いまで含めて整理します。
ONとUSINGの違いを先にまとめる
| 観点 | ON句 | USING句 |
|---|---|---|
| 列名 | 違う列名でも使える | 同じ列名が必要 |
| 条件 | 任意の条件を書ける | 指定列の等価結合 |
| 複数条件 | 書きやすい | 複雑な条件には不向き |
| 結果列 | 結合列が左右両方出ることがある | 結合列は1列にまとまる |
| 可読性 | 明示的で安全 | シンプルで短い |
迷ったら、まずはONを使うと安全です。列名が完全に揃っていて、単純な等価結合だけならUSINGも読みやすいです。
SQL JOINとは?
JOINは、2つ以上のテーブルを関連する列で結びつけ、1つの結果として取得する仕組みです。
たとえば、顧客テーブルcustomersと注文テーブルordersがあるとします。
customers
---------
customer_id | name
1 | Sato
2 | Suzuki
orders
------
order_id | customer_id | total_amount
101 | 1 | 3000
102 | 2 | 5000
この2つをcustomer_idでJOINすると、「誰がいくら注文したか」を1つの結果として取得できます。
SELECT customers.name, orders.total_amount
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id;
JOINの主な種類
- INNER JOIN
両方のテーブルに一致する行だけを取得します。 - LEFT JOIN
左側のテーブルをすべて残し、右側にない部分はNULLになります。 - RIGHT JOIN
右側のテーブルをすべて残し、左側にない部分はNULLになります。 - FULL JOIN
両方のテーブルの行を残します。DBによっては対応していない場合があります。
ONとUSINGは、これらのJOINで「どの列を使って結合するか」を指定するために使います。
ON句とUSING句の違いとは?
ON句の使い方
ONは、結合条件を自由に書ける句です。
同じ列名でも使えます。
SELECT customers.name, orders.total_amount
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id;
列名が違う場合も使えます。
SELECT customers.name, orders.total_amount
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.buyer_id;
さらに、複数条件も書けます。
SELECT customers.name, orders.total_amount
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id
AND orders.status = 'paid';
ONは明示的で、複雑な条件にも対応しやすいのが強みです。
USING句の使い方
USINGは、両方のテーブルに同じ名前の列がある場合に使えます。
SELECT customers.name, orders.total_amount
FROM customers
INNER JOIN orders
USING (customer_id);
USING (customer_id)は、ざっくりいうと次の条件を書く省略形です。
ON customers.customer_id = orders.customer_id
ただし、完全に同じではありません。大きな違いは、SELECT *したときの結果列です。
SELECT * の結果列が変わる
ONとUSINGで分かりやすく違うのが、結合後の列の出方です。
ONの場合
SELECT *
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id;
この場合、DBや表示方法によってはcustomers.customer_idとorders.customer_idの両方が結果に出ます。
USINGの場合
SELECT *
FROM customers
INNER JOIN orders
USING (customer_id);
この場合、customer_idは1列にまとまります。
PostgreSQLのドキュメントでも、JOIN ONは左右テーブルの列を出し、JOIN USINGは指定した結合列を1列にまとめる、と説明されています。
ON句を使うべき場合
1. 結合する列名が違う
SELECT customers.name, orders.total_amount
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.buyer_id;
USINGは同じ列名でないと使えないため、このケースではONを使います。
2. 複数条件で結合したい
SELECT customers.name, orders.total_amount
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id
AND customers.tenant_id = orders.tenant_id;
マルチテナントのように、customer_idだけでなくtenant_idも合わせたい場合はONが分かりやすいです。
3. 条件に絞り込みを含めたい
SELECT customers.name, orders.total_amount
FROM customers
LEFT JOIN orders
ON customers.customer_id = orders.customer_id
AND orders.status = 'paid';
LEFT JOINでは、条件をONに書くかWHEREに書くかで結果が変わることがあります。JOIN条件として扱いたいものはONに書くと意図が明確です。
USING句を使うべき場合
1. 両方のテーブルに同じ列名がある
SELECT customers.name, orders.total_amount
FROM customers
INNER JOIN orders
USING (customer_id);
両方のテーブルにcustomer_idがあり、その列で単純に等価結合するならUSINGは短く書けます。
2. 結果列をすっきりさせたい
SELECT *
FROM customers
INNER JOIN orders
USING (customer_id);
SELECT *したときに、結合列が1つにまとまります。分析用SQLや一時的な確認では見やすくなります。
3. 複数の同名列で結合したい
USINGには複数列も指定できます。
SELECT customers.name, orders.total_amount
FROM customers
INNER JOIN orders
USING (tenant_id, customer_id);
ただし、列名が同じであることが前提です。
ONとUSINGの注意点
USINGは列名変更に弱い
USING (customer_id)は短く書けますが、どちらかのテーブルで列名が変わると使えません。将来の変更に強くしたい場合は、ONで明示したほうが読みやすいことがあります。
SELECT * に頼りすぎない
USINGでは結合列が1列にまとまるため便利ですが、実務では必要な列を明示するほうが安全です。
SELECT
customers.customer_id,
customers.name,
orders.total_amount
FROM customers
INNER JOIN orders
USING (customer_id);
NATURAL JOINは慎重に使う
NATURAL JOINは同名列を自動で使ってJOINします。一見便利ですが、意図しない同名列が増えたときに結果が変わる可能性があります。初心者のうちは、ONまたはUSINGで明示するのがおすすめです。
DBによって挙動や対応範囲が違う
PostgreSQL、MySQL、SQLiteなど、多くのDBでUSINGは使えます。ただし、細かい構文や対応するJOIN種別、結果列の扱いはDBごとに差があります。実務では使っているDBの公式ドキュメントを確認してください。
結論: ONとUSING、どちらを使うべきか?
基本方針は次の通りです。
- 迷ったら
ON - 列名が違うなら
ON - 複数条件や複雑な条件なら
ON - 同じ列名で単純に結合するなら
USING SELECT *の結果列をすっきりさせたいならUSING
個人的には、アプリケーションコードや長く残るSQLではONで明示することが多いです。一方で、分析SQLや一時的な確認ではUSINGが読みやすい場面もあります。
よくある質問
ONとUSINGは処理速度が違いますか?
基本的には、同じ等価結合なら大きな差を気にする場面は少ないです。速度よりも、インデックス、結合するデータ量、実行計画の影響が大きいです。
USINGは同じ列名ならいつでも使ってよいですか?
使えますが、同じ列名が必ず同じ意味とは限りません。たとえばidのような列名は、各テーブルの主キーを指していることが多く、安易にUSING (id)すると意図しないJOINになります。
LEFT JOINでもUSINGは使えますか?
使えます。
SELECT customers.name, orders.total_amount
FROM customers
LEFT JOIN orders
USING (customer_id);
ただし、LEFT JOINでは条件をON側に置くかWHERE側に置くかで結果が変わることがあるため、複雑な条件ではONで明示したほうが安全です。
まとめ
SQL JOINのONとUSINGは、どちらも結合条件を書くためのものですが、使える場面と結果列に違いがあります。
ONは柔軟で明示的USINGは同じ列名の等価結合を短く書けるUSINGでは結合列が1列にまとまる- 実務では、迷ったら
ONで明示するのが安全
まずはONでJOINの考え方を理解し、同名列の単純なJOINでUSINGを試すと、違いがつかみやすいです。