SQL JOIN-WHERE句とON句


686

それを読んだ後、これは明示的SQL結合と暗黙的SQL結合の複製ではありません。答えは関連している(または同じ)場合もありますが、質問は異なります。


違いは何ですか?それぞれに何を入れるべきですか?

理論を正しく理解していれば、クエリオプティマイザーは両方を同じ意味で使用できるはずです。


2
将来の読者とあなたの情報のためだけに、SQLの実行順序を読んでください。これは、根本的な違いをより正確に理解するのに役立ちます。
Rahul Neekhra 2017年

回答:


869

彼らは同じものではありません。

次のクエリを検討してください。

SELECT *
FROM Orders
LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID
WHERE Orders.ID = 12345

そして

SELECT *
FROM Orders
LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID 
    AND Orders.ID = 12345

1つ目は、注文番号とそれに対応する注文番号(ある場合)を返し12345ます。2番目はすべての注文を返しますが、注文のみが12345関連付けられた行を持ちます。

を使用するINNER JOINと、句は実質的に同等になります。ただし、機能的に同じであっても、同じ結果が得られるというだけでは、2種類の句の意味が同じであるとは限りません。


83
where句を内部結合の "on"句に入れると、パフォーマンスが向上しますか?
FistOfFury

96
@FistOfFury Sql Serverは、コードをコンパイルして評価するクエリオプティマイザープロシージャを使用して、可能な限り最適な実行プランを作成します。完璧ではありませんが、ほとんどの場合は問題ではなく、どちらの方法でも同じ実行プランが得られます。
Joel Coehoorn

18
Postgresでは、これらは同等ではなく、クエリプランが異なることに気付きました。ONを使用すると、マテリアライズが使用されます。WHEREを使用した場合は、ハッシュを使用しました。マテリアライズには、ハッシュよりも10倍もコストがかかる最悪のケースがありました。これは、単一のIDではなく、一連のIDを使用していました。
JamesHutchison

13
@JamesHutchisonこのような観測された動作に基づいて、信頼性の高いパフォーマンスの一般化を行うのは困難です。これは文書化された動作ではなく実装の詳細であるため、ある日は真実でしたが、次の日は間違いがちになります。データベースチームは、オプティマイザのパフォーマンスを向上させる場所を常に探しています。ONの動作がWHEREに一致するように改善されない場合、私は驚かれます。それも、バージョンからの一般的なパフォーマンスの向上」のようなもの以外のバージョンにリリースノートにどこにも表示されない場合があります。
ジョエルCoehoorn

4
@FiHoranそれはSQL Serverの動作方法ではありません。統計が有用であると示した場合、WHERE句の項目に基づいて積極的に事前フィルタリングします。
Joel Coehoorn、2018年

362
  • 内部結合には関係ありません
  • 外部結合の問題

    a。WHERE句:入社。結合が行われた後、レコードはフィルタリングされます。

    b。ON句- 参加する前。結合する前に(右側のテーブルの)レコードがフィルターされます。これは結果としてnullになる可能性があります(OUTER結合以降)。



:以下の表を検討してください。

    1. documents:
     | id    | name        |
     --------|-------------|
     | 1     | Document1   |
     | 2     | Document2   |
     | 3     | Document3   |
     | 4     | Document4   |
     | 5     | Document5   |


    2. downloads:
     | id   | document_id   | username |
     |------|---------------|----------|
     | 1    | 1             | sandeep  |
     | 2    | 1             | simi     |
     | 3    | 2             | sandeep  |
     | 4    | 2             | reya     |
     | 5    | 3             | simi     |

a)内側のWHERE句:

  SELECT documents.name, downloads.id
    FROM documents
    LEFT OUTER JOIN downloads
      ON documents.id = downloads.document_id
    WHERE username = 'sandeep'

 For above query the intermediate join table will look like this.

    | id(from documents) | name         | id (from downloads) | document_id | username |
    |--------------------|--------------|---------------------|-------------|----------|
    | 1                  | Document1    | 1                   | 1           | sandeep  |
    | 1                  | Document1    | 2                   | 1           | simi     |
    | 2                  | Document2    | 3                   | 2           | sandeep  |
    | 2                  | Document2    | 4                   | 2           | reya     |
    | 3                  | Document3    | 5                   | 3           | simi     |
    | 4                  | Document4    | NULL                | NULL        | NULL     |
    | 5                  | Document5    | NULL                | NULL        | NULL     |

  After applying the `WHERE` clause and selecting the listed attributes, the result will be: 

   | name         | id |
   |--------------|----|
   | Document1    | 1  |
   | Document2    | 3  | 

b)内部JOIN条項

  SELECT documents.name, downloads.id
  FROM documents
    LEFT OUTER JOIN downloads
      ON documents.id = downloads.document_id
        AND username = 'sandeep'

For above query the intermediate join table will look like this.

    | id(from documents) | name         | id (from downloads) | document_id | username |
    |--------------------|--------------|---------------------|-------------|----------|
    | 1                  | Document1    | 1                   | 1           | sandeep  |
    | 2                  | Document2    | 3                   | 2           | sandeep  |
    | 3                  | Document3    | NULL                | NULL        | NULL     |
    | 4                  | Document4    | NULL                | NULL        | NULL     |
    | 5                  | Document5    | NULL                | NULL        | NULL     |

Notice how the rows in `documents` that did not match both the conditions are populated with `NULL` values.

After Selecting the listed attributes, the result will be: 

   | name       | id   |
   |------------|------|
   |  Document1 | 1    |
   |  Document2 | 3    | 
   |  Document3 | NULL |
   |  Document4 | NULL | 
   |  Document5 | NULL | 

40
IMOこれは、他の一般的な回答の「内部」で何が起こっているかを明確に示すため、これが最良の回答です。
psrpsrpsr

1
優れた説明....よくやった!-それを取得するために何をしたのですintermediate join tableか?「説明」コマンドはありますか?
マヌエルジョーダン

1
@ManuelJordanいいえ、これは説明用です。データベースは、中間テーブルを作成するよりもパフォーマンスが高い場合があります。
Sandeep Jindal

おそらく、3つ目のツールが使用されたと思います。
Manuel Jordan

145

INNER JOINそれらは交換可能であり、オプティマイザはそれらを自由に再配置します。

OUTER JOINの、彼らはそれが依存参加のどちら側に応じて、必ずしも互換性はありません。

読みやすさに応じて、どちらか一方に置きます。



Where句、特にLinq-To-Entitiesのラムダ式の場合は、より明確になりますOrders.Join( OrderLines, x => x.ID, x => OrderID, (o,l) => new {Orders = o, Lines = l}).Where( ol => ol.Orders.ID = 12345)
Triynko

49

私のやり方は:

  • ONを行う場合は、常に結合条件を句に入れてくださいINNER JOIN。したがって、ON句にWHERE条件を追加せずに、句に入れますWHERE

  • を実行している場合は、結合の右側にあるテーブルLEFT JOINON句にWHERE条件を追加します。結合の右側を参照するWHERE句を追加すると、結合がINNER JOINに変換されるため、これは必須です。

    例外は、特定のテーブルにないレコードを探す場合です。次のようにして、RIGHT JOINテーブルの一意の識別子(NULLではない)への参照をWHERE句に追加しますWHERE t2.idfield IS NULL。したがって、結合の右側にあるテーブルを参照する必要があるのは、テーブルにないレコードを見つけるときだけです。


8
これは、これまでに読んだ最良の答えです。左結合が左テーブルのすべての行返すことを理解し、後でフィルタリングする必要があることを脳が理解したら、完全に意味があります。
Nick Larsen 2013

null可能な列を持つテーブルを外部結合する場合、その列を内部結合せずに、その列をnullにすることはできますか?これは、特定のテーブルにのみ存在しないレコードを正確に探すことではありません。1.存在しない2.まったく価値がないを検索できます。
付近

つまり、「1。存在しない2.まったく価値がない」の両方を一緒に検索できるということです。そして、これはそのフィールドがidfieldではない場合に適用されます。
付近

私がこのケースに遭遇したとき:緊急連絡なしに新入生(まだ入力されていない)を含む参加者を探しています。
付近

30

内部結合では、これらは同じことを意味します。ただし、結合条件をWHERE句とON句のどちらに指定するかによって、外部結合では異なる結果が得られます。見てみましょう。この関連の質問およびこの答え(私が)を。

それはあなたのクエリを読む誰にとってもそれを明確にするので、それが外部句であり、あなたが実際にwhere句でそれを望んでいない限り)ON句に常に結合条件を置く習慣にあることが最も理にかなっていると思いますテーブルが結合されている条件。また、WHERE句が数十行になるのを防ぐのにも役立ちます。


26

これは非常に一般的な質問なので、この回答は私が書いたこの記事に基づいています。

テーブルの関係

私たちは以下の持って考えるpostpost_commentテーブルを:

<code> post </ code>および<code> post_comment </ code>テーブル

post次のレコードがあります。

| id | title     |
|----|-----------|
| 1  | Java      |
| 2  | Hibernate |
| 3  | JPA       |

そして、post_comment次の3つの行があります。

| id | review    | post_id |
|----|-----------|---------|
| 1  | Good      | 1       |
| 2  | Excellent | 1       |
| 3  | Awesome   | 2       |

SQL内部結合

SQL JOIN句を使用すると、異なるテーブルに属する行を関連付けることができます。たとえば、CROSS JOINは、2つの結合するテーブル間の行のすべての可能な組み合わせを含むデカルト積を作成します。

CROSS JOINは特定のシナリオで役立ちますが、ほとんどの場合、特定の条件に基づいてテーブルを結合する必要があります。そして、そこがINNER JOINの出番です。

SQL INNER JOINを使用すると、ON句で指定された条件に基づいて、2つのテーブルを結合するデカルト積をフィルタリングできます。

SQL INNER JOIN-ON「常に真」の条件

「常に真」の条件を指定した場合、INNER JOINは結合されたレコードをフィルタリングせず、結果セットには2つの結合テーブルのデカルト積が含まれます。

たとえば、次のSQL INNER JOINクエリを実行するとします。

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 1

postpost_commentレコードのすべての組み合わせを取得します。

| p.id    | pc.id      |
|---------|------------|
| 1       | 1          |
| 1       | 2          |
| 1       | 3          |
| 2       | 1          |
| 2       | 2          |
| 2       | 3          |
| 3       | 1          |
| 3       | 2          |
| 3       | 3          |

したがって、ON句の条件が「常にtrue」の場合、INNER JOINはCROSS JOINクエリと同じです。

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 1
ORDER BY p.id, pc.id

SQL INNER JOIN-ON「常にfalse」条件

一方、ON句の条件が「常にfalse」の場合、結合されたすべてのレコードがフィルターで除外され、結果セットは空になります。

したがって、次のSQL INNER JOINクエリを実行すると、

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 0
ORDER BY p.id, pc.id

結果は返されません。

| p.id    | pc.id      |
|---------|------------|

これは、上記のクエリが次のCROSS JOINクエリと同等であるためです。

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 0
ORDER BY p.id, pc.id

SQL INNER JOIN-外部キー列と主キー列を使用するON句

最も一般的なON句の条件は、次のクエリに示すように、子テーブルの外部キー列と親テーブルの主キー列が一致する条件です。

SELECT
   p.id AS "p.id",
   pc.post_id AS "pc.post_id",
   pc.id AS "pc.id",
   p.title AS "p.title",
   pc.review  AS "pc.review"
FROM post p
INNER JOIN post_comment pc ON pc.post_id = p.id
ORDER BY p.id, pc.id

上記のSQL INNER JOINクエリを実行すると、次の結果セットが得られます。

| p.id    | pc.post_id | pc.id      | p.title    | pc.review |
|---------|------------|------------|------------|-----------|
| 1       | 1          | 1          | Java       | Good      |
| 1       | 1          | 2          | Java       | Excellent |
| 2       | 2          | 3          | Hibernate  | Awesome   |

したがって、ON句の条件に一致するレコードのみがクエリ結果セットに含まれます。私たちの場合、結果セットにはすべてのレコードpostとそのpost_commentレコードが含まれています。post無関連した行はpost_comment、彼らがON句の条件を満たすことができないため、除外されています。

ここでも、上記のSQL INNER JOINクエリは、次のCROSS JOINクエリと同等です。

SELECT
   p.id AS "p.id",
   pc.post_id AS "pc.post_id",
   pc.id AS "pc.id",
   p.title AS "p.title",
   pc.review  AS "pc.review"
FROM post p, post_comment pc
WHERE pc.post_id = p.id

非ストライク行はWHERE句を満たす行であり、これらのレコードのみが結果セットに含まれます。これが、INNER JOIN句の動作を視覚化する最良の方法です。

| p.id | pc.post_id | pc.id | p.title | pc.review |
| ------ | ------------ | ------- | ----------- | --------- -|
| 1 | 1 | 1 | Java | 良い|
| 1 | 1 | 2 | Java | 素晴らしい|
| 1 | 2 | 3 | Java | 素晴らしい| 
| 2 | 1 | 1 | ハイバネート| 良い| 
| 2 | 1 | 2 | ハイバネート| 素晴らしい|
| 2 | 2 | 3 | ハイバネート| 素晴らしい|
| 3 | 1 | 1 | JPA | 良い| 
| 3 | 1 | 2 | JPA | 素晴らしい| 
| 3 | 2 | 3 | JPA | 素晴らしい|

結論

INNER JOINステートメントは、INNER JOINクエリのON句で使用したのと同じ条件に一致するWHERE句を含むCROSS JOINとして書き換えることができます。

これはINNER JOINにのみ適用され、OUTER JOINには適用されません。


11

左結合に関しては、where句on句には大きな違いがあります。

次に例を示します。

mysql> desc t1; 
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   |     | NULL    |       |
| fid   | int(11)     | NO   |     | NULL    |       |
| v     | varchar(20) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

テーブルt2のidがあります。

mysql> desc t2;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   |     | NULL    |       |
| v     | varchar(10) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

「on句」に対するクエリ:

mysql> SELECT * FROM `t1` left join t2 on fid = t2.id AND t1.v = 'K' 
    -> ;
+----+-----+---+------+------+
| id | fid | v | id   | v    |
+----+-----+---+------+------+
|  1 |   1 | H | NULL | NULL |
|  2 |   1 | B | NULL | NULL |
|  3 |   2 | H | NULL | NULL |
|  4 |   7 | K | NULL | NULL |
|  5 |   5 | L | NULL | NULL |
+----+-----+---+------+------+
5 rows in set (0.00 sec)

「where句」に対するクエリ:

mysql> SELECT * FROM `t1` left join t2 on fid = t2.id where t1.v = 'K';
+----+-----+---+------+------+
| id | fid | v | id   | v    |
+----+-----+---+------+------+
|  4 |   7 | K | NULL | NULL |
+----+-----+---+------+------+
1 row in set (0.00 sec)

行t1.v = 'K'の場合、最初のクエリがt1からのレコードと、t2からの従属行(ある場合)を返すことは明らかです。

2番目のクエリはt1から行を返しますが、t1.v = 'K'の場合のみ、それに関連付けられた行があります。


9

オプティマイザに関しては、結合句をONとWHEREのどちらで定義しても違いはありません。

ただし、私見では、結合を実行するときにON句を使用する方がはるかに明確だと思います。このようにして、クエリの特定のセクションで、結合の処理方法と、残りのWHERE句との混合方法を指定します。


7

それらのテーブルを考えてみましょう:

id | SomeData

B

id | id_A | SomeOtherData

id_A テーブルへの外部キーであること A

このクエリを書く:

SELECT *
FROM A
LEFT JOIN B
ON A.id = B.id_A;

この結果を提供します:

/ : part of the result
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////+-------+-------------------------+
|/////////////////////////////|
+-----------------------------+

AにはあるがBにはないということは、Bにnull値があることを意味します。


次に、の特定の部分を検討B.id_Aし、前の結果から強調表示します。

/ : part of the result
* : part of the result with the specific B.id_A
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////+---+///|                         |
|/////////////////////|***|///|                         |
|/////////////////////+---+---+-------------------------+
|/////////////////////////////|
+-----------------------------+

このクエリを書く:

SELECT *
FROM A
LEFT JOIN B
ON A.id = B.id_A
AND B.id_A = SpecificPart;

この結果を提供します:

/ : part of the result
* : part of the result with the specific B.id_A
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|/////////////////////|       |                         |
|/////////////////////|       |                         |
|/////////////////////+---+   |                         |
|/////////////////////|***|   |                         |
|/////////////////////+---+---+-------------------------+
|/////////////////////////////|
+-----------------------------+

これにより、内部結合の中にない値が削除されるため B.id_A = SpecificPart


次に、クエリを次のように変更します。

SELECT *
FROM A
LEFT JOIN B
ON A.id = B.id_A
WHERE B.id_A = SpecificPart;

結果は次のとおりです。

/ : part of the result
* : part of the result with the specific B.id_A
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|                     |       |                         |
|                     |       |                         |
|                     +---+   |                         |
|                     |***|   |                         |
|                     +---+---+-------------------------+
|                             |
+-----------------------------+

結果全体が、Aにあり、BにはないB.id_A = SpecificPartパーツの削除に対してフィルターされているためB.id_A = NULL


4

データを結合したり、データをフィルタリングしたりしていますか?

読みやすくするために、これらのユースケースをそれぞれONとWHEREに分離することが最も理にかなっています。

  • ONでデータを結合する
  • WHEREでデータをフィルタリングする

JOIN条件とフィルタリング条件がWHERE句に存在するクエリを読み取るのが非常に難しくなる可能性があります。

パフォーマンスに関しては、違いはないはずですが、SQLの種類によってはクエリの計画が異なる場合があるため、試す価値があります¯\_(ツ)_/¯(クエリの速度に影響するキャッシュに注意してください)。

また、他の人が述べたように、外部結合を使用する場合、ON句にフィルター条件を配置すると、テーブルの1つにのみ影響するため、異なる結果が得られます。

私はこれについてもっと深く投稿しました:https : //dataschool.com/learn/difference-between-where-and-on-in-sql


2

SQLでは、 'WHERE'句と 'ON'句は条件付きステートマントの一種ですが、それらの主な違いは、条件を指定するためにSelect / Updateステートメントで 'Where'句が使用されるのに対し、 'ON'句はテーブルが結合される前に、ターゲットテーブルとソーステーブルでレコードが一致するかどうかを検証またはチェックする結合で使用されます。

例:-'WHERE'

SELECT * FROM employee WHERE employee_id=101

例:-'ON'

2つのテーブルemployeeとemployee_detailsがあり、一致する列はemployee_idです。

SELECT * FROM employee 
INNER JOIN employee_details 
ON employee.employee_id = employee_details.employee_id

私があなたの質問に答えてくれれば幸いです。明確化のために元に戻します。


しかしWHERE、の代わりにキーワードを使用ONできますね。sqlfiddle.com/#!2/ae5b0/14/0
Qwerty

1

ジョインシーケンス効果だと思います。左上結合の場合、SQLは最初に左結合を実行し、次にwhereフィルターを実行します。下のケースでは、まずOrders.ID = 12345を見つけてから、結合を行います。


1

内部結合の場合WHEREON互換的に使用できます。実際、ON相関サブクエリで使用することは可能です。例えば:

update mytable
set myscore=100
where exists (
select 1 from table1
inner join table2
on (table2.key = mytable.key)
inner join table3
on (table3.key = table2.key and table3.key = table1.key)
...
)

これは(IMHO)人間を完全に混乱させるものであり、table1何かにリンクすることを忘れることは非常に簡単です( "driver"テーブルには "on"句がないため)が、それは合法です。


1

パフォーマンスを向上させるには、テーブルにJOINSに使用する特別なインデックス付きの列が必要です。

したがって、条件付けする列がこれらのインデックス付き列の1つではない場合、それをWHEREに保持することをお勧めします。

したがって、インデックス付きの列を使用してJOINし、JOINの後、インデックスのない列で条件を実行します。


1

通常、2つのテーブルがすでに結合されていると、フィルタリングはWHERE句で処理されます。ただし、結合する前に、一方または両方のテーブルをフィルター処理することもできます。つまり、where句は結果セット全体に適用されますが、on句は問題の結合にのみ適用されます。


これは、DBMSが「通常」最適化するため、そうではありません。
philipxy

1

この違いは、SQLでの操作論理的な順序によって説明するのが最も簡単だと思います。

  • FROM (結合を含む)
  • WHERE
  • GROUP BY
  • 集計
  • HAVING
  • WINDOW
  • SELECT
  • DISTINCT
  • UNIONINTERSECTEXCEPT
  • ORDER BY
  • OFFSET
  • FETCH

結合は、selectステートメントの句ではなく、内の演算子ですFROM。したがってON、対応するJOIN演算子に属するすべての句は、論理処理が句に到達するまでに、論理的に「すでに発生」していWHEREます。これは、LEFT JOINたとえばの場合、外部結合のセマンティクスは、WHERE句が適用されるときまでにすでに発生していることを意味します。

このブログ投稿では、次の例について詳しく説明しています。このクエリを実行すると:

SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
WHERE film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;

LEFT JOIN俳優が映画でプレーしていない場合でも、そのように俳優は、フィルタリングされるので、本当に、任意の有用な効果を持っていないFILM_IDだろうNULLWHERE節は、そのような行をフィルタリングします。結果は次のようになります。

ACTOR_ID  FIRST_NAME  LAST_NAME  COUNT
--------------------------------------
194       MERYL       ALLEN      1
198       MARY        KEITEL     1
30        SANDRA      PECK       1
85        MINNIE      ZELLWEGER  1
123       JULIANNE    DENCH      1

つまり、2つのテーブルを内部結合したかのようにです。ON句でフィルター述語を移動すると、それが外部結合の基準になります。

SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
  AND film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;

結果には、映画のない俳優、または映画のない俳優が含まれます FILM_ID < 10

ACTOR_ID  FIRST_NAME  LAST_NAME     COUNT
-----------------------------------------
3         ED          CHASE         0
4         JENNIFER    DAVIS         0
5         JOHNNY      LOLLOBRIGIDA  0
6         BETTE       NICHOLSON     0
...
1         PENELOPE    GUINESS       1
200       THORA       TEMPLE        1
2         NICK        WAHLBERG      1
198       MARY        KEITEL        1

要するに

述語は常に論理的に最も意味のある場所に置いてください。


0

あなたの質問について、

サーバーが取得できる限り、内部結合の「on」または「where」はどちらでも同じです。

select * from a inner join b on a.c = b.c

そして

select * from a inner join b where a.c = b.c

'where'オプションはすべての通訳者が知っているわけではないので、おそらく避けるべきです。そしてもちろん、 'on'句はより明確です。


-5

これが私の解決策です。

SELECT song_ID,songs.fullname, singers.fullname
FROM music JOIN songs ON songs.ID = music.song_ID  
JOIN singers ON singers.ID = music.singer_ID
GROUP BY songs.fullname

それを機能させるに、が必要GROUP BYです。

この助けを願っています。


10
song_idとsingers.fullnameも選択しているときに、songs.fullnameのみでグループ化すると、ほとんどのデータベースで問題になります。
btilly
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.