SQLでテーブルを結合するとき、JOIN ... ONJOIN ... 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によっては対応していない場合があります。

ONUSINGは、これらの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_idorders.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のONUSINGは、どちらも結合条件を書くためのものですが、使える場面と結果列に違いがあります。

  • ONは柔軟で明示的
  • USINGは同じ列名の等価結合を短く書ける
  • USINGでは結合列が1列にまとまる
  • 実務では、迷ったらONで明示するのが安全

まずはONでJOINの考え方を理解し、同名列の単純なJOINでUSINGを試すと、違いがつかみやすいです。

参考資料と関連トピックス