MySQLクエリで、なぜwhereではなくjoinを使用するのですか?


108

2つ以上のテーブルを組み合わせるようですが、結合または場所を使用できます。一方が他方よりも優れている点は何ですか?


2
使用方法によっては同じ結果になる可能性がありますが、JOINを使用すると、他の種類の関連付けを行うことができます。
zneak 2010

これはあなたの質問に答えますか?INNER JOIN ONとWHERE句
philipxy

回答:


160

複数のテーブルが関係するクエリでは、テーブル "A"の結果をテーブル "B"にリンクするための何らかの関連付けが必要です。これを行う従来の(ANSI-89)方法は次のとおりです。

  1. FROM句のカンマ区切りリストに含まれるテーブルをリストします
  2. テーブル間の関連付けをWHERE句に記述します

    SELECT *
      FROM TABLE_A a,
           TABLE_B b
     WHERE a.id = b.id

ANSI-92 JOIN構文を使用して書き換えられたクエリは次のとおりです。

SELECT *
  FROM TABLE_A a
  JOIN TABLE_B b ON b.id = a.id

パフォーマンスの観点から:


サポートされている場合(Oracle 9i +、PostgreSQL 7.2 +、MySQL 3.23 +、SQL Server 2000+)、どちらの構文を使用してもパフォーマンス上の利点はありません。オプティマイザはそれらを同じクエリと見なします。ただし、より複雑なクエリでは、ANSI-92構文を使用することでメリットが得られます。

  • JOIN順序を制御する機能-テーブルがスキャンされる順序
  • 結合前にテーブルにフィルター基準を適用する機能

メンテナンスの観点から:


ANSI-89ではなくANSI-92 JOIN構文を使用する理由は数多くあります。

  • JOIN基準はWHERE句とは別であるため、より読みやすい
  • JOIN基準を逃しにくい
  • INNER以外のJOIN型の一貫した構文サポートにより、他のデータベースでクエリを使いやすくします
  • WHERE句は、結合されたテーブルのデカルト積のフィルタリングとしてのみ機能します

設計の観点から:


ANSI-92 JOIN構文はパターンであり、アンチパターンではありません。

  • クエリの目的はより明白です。アプリケーションが使用する列は明確です
  • これは、可能な場合は常に厳密な型指定を使用することに関するモジュール規則に従います。Explicitはほぼ例外なく優れています。

結論


親しみやすさや快適さがない限り、ANSI-92 JOIN構文の代わりにANSI-89 WHERE句を使い続けることには何のメリットもありません。ANSI-92構文の方が冗長であると文句を言う人もいるかもしれませんが、それがそれを明示的にしています。明示的であるほど、理解と保守が容易になります。


14
"...複数のテーブルを含むクエリでは、テーブル 'A'からテーブル 'B'への結果をリンクするために何らかの関連付けが必要です...そうでない場合、デカルト積を取得しますが、おそらくそれを望まないでしょう。 (デカルト人はルーシーな製品を作っています。)
スコット・スミス

8

ほとんどの人は、JOIN構文が、何に何が結合されるかについて、より明確であると考える傾向があります。さらに、標準であるという利点もあります。

個人的に、私はWHEREで「成長」しましたが、JOIN構文を使用すればするほど、それがいかに明確であるかがわかり始めます。


1
@nawfalわかりました-古いスタイルの構文に慣れましたが、新しい構文に慣れると、たとえば誤ってクロスジョインを実行するのが難しくなり、明示的になり、ジョインとは何かがわかりやすくなります。フィルターなど…夢中になりました。
基本

8

これらは、where構文の使用に関する問題です(そうでない場合は、暗黙的な結合とも呼ばれます)。

まず、結合条件がテーブル名のすぐ隣にないため、偶発的なクロス結合が発生するのは非常に簡単です。6つのテーブルが結合されている場合、where句の1つを見逃しがちです。あなたはdistinctキーワードを使用することによって、これがあまりにも頻繁に修正されるのを見るでしょう。これは、データベースにとって非常に大きなパフォーマンスヒットです。明示的な結合構文を使用すると、構文チェックに失敗するため、偶発的なクロス結合を取得できません。

一部のデータベースの古い構文では、右と左の結合に問題があります(SQlサーバーでは正しい結果が得られるとは限りません)。さらに、それらは私が知っているSQL Serverでは非推奨です。

クロス結合を使用する場合、古い構文からは明確ではありません。現在のANSII標準を使用することは明らかです。

暗黙の構文を使用して、どのフィールドが結合の一部であるか、またはどのテーブルがどの順序で結合されるかさえ正確に確認することは、メンテナーにとってはるかに困難です。これは、クエリの修正に時間がかかる可能性があることを意味します。明示的な結合構文に慣れると、以前の方法に戻った人はほとんどいません。

また、これらの暗黙的な結合を使用する一部の人々は、結合がどのように機能するかを実際に理解していないため、クエリで誤った結果を取得していることに気づきました。

正直なところ、18年前により良い方法に置き換えられた他の種類のコードを使用しますか?


6

明示的な結合は意図を伝え、フィルタリングを行うwhere句を残します。すっきりとしていてスタンダードで、左アウターや右アウターなど、どこでしかやりにくいことができます。


3

WHEREを使用して2つのテーブルを結合することはできません。しかし、あなたができることは書くことです:

SELECT * FROM A, B
WHERE ...

ここのコンマは、次のように書くことと同じです。

SELECT *
FROM A
CROSS JOIN B
WHERE ...

書いていただけますか?いいえ-それはあなたが何を意味するのかではないので。クロス結合ではなく、INNER JOINが必要です。しかし、コンマを書くときは、CROSS JOINと言っているので混乱します。


0

実際、「WHERE」と「JOIN」の両方が必要になることがよくあります。

"JOIN"は、共通の列の値に基づいて、2つのテーブルからデータを取得するために使用されます。その後、この結果をさらにフィルタリングする場合は、WHERE句を使用します。

たとえば、「LEFT JOIN」は、左側のテーブルからすべての行を取得し、さらに右側のテーブルから一致する行を取得します。ただし、特定の値またはJOINの一部ではない他の列のレコードはフィルターされません。したがって、この結果をさらにフィルタリングする場合は、WHERE句で追加のフィルターを指定します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.