w3school - sql server join




Jointure SQL: clause where vs clause (10)

Après l'avoir lu, il ne s'agit pas d' un doublon de jointures SQL explicites ou implicites . La réponse peut être liée (ou même la même) mais la question est différente.

Quelle est la différence et que devrait-on y faire?

Si je comprends bien la théorie, l'optimiseur de requête devrait être capable d'utiliser les deux de façon interchangeable.


Ce n'est pas la même chose.

Considérez ces requêtes:

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

et

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

Le premier renverra une commande et ses lignes, le cas échéant, pour le numéro de commande 12345 . La seconde retournera toutes les commandes, mais seulement l'ordre 12345 aura des lignes qui lui sont associées.

Avec une INNER JOIN , les clauses sont effectivement équivalentes. Cependant, ce n'est pas parce qu'ils sont fonctionnellement identiques, parce qu'ils produisent les mêmes résultats, que les deux types de clauses ont la même signification sémantique.


En SQL, la clause 'WHERE' et 'ON' sont une sorte de Statemants conditionnels, mais la différence majeure entre eux est que la clause 'Where' est utilisée dans Select / Update Statements pour spécifier les conditions, alors que la clause 'ON' est utilisé dans les jointures, où il vérifie ou vérifie si les enregistrements sont appariés dans les tables cible et source, avant que les tables ne soient jointes

Par exemple: - 'OERE'

SELECT * FROM employé WHERE employee_id = 101

Par exemple: - 'ON'

* Il y a deux tables employee et employee_details, les colonnes correspondantes sont employee_id. *

SELECT * DE l'employé INNER JOIN employee_details ON employee.employee_id = employee_details.employee_id

J'espère avoir répondu à votre question.Retourner pour des clarifications.


Il y a une grande différence entre la clause where et la clause on , quand il s'agit de la jointure à gauche.

Voici un exemple:

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

Il y a id id de la table t2.

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)

Requête sur "on clause":

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)

Requête sur "where clause":

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)

Il est clair que la première requête renvoie un enregistrement de t1 et sa ligne dépendante de t2, le cas échéant, pour la ligne t1.v = 'K'.

La deuxième requête renvoie les lignes de t1, mais seulement pour t1.v = 'K' aura une ligne associée avec elle.


Je pense que c'est l'effet de séquence de jointure. Dans le cas de jointure supérieur gauche, SQL do Left se joint d'abord, puis effectue le filtrage. Dans le cas inférieur, recherchez d'abord Orders.ID = 12345, puis faites-le.


Normalement, le filtrage est traité dans la clause WHERE une fois que les deux tables ont déjà été jointes. Il est possible, bien que vous souhaitiez filtrer une ou les deux tables avant de les rejoindre. c'est-à-dire que la clause where s'applique à l'ensemble des résultats alors que la clause on ne s'applique qu'à la jointure en question.


Pour une jointure interne, WHERE et ON peuvent être utilisés de manière interchangeable. En fait, il est possible d'utiliser ON dans une sous-requête corrélée. Par exemple:

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)
...
)

C'est (IMHO) totalement confus à un humain, et il est très facile d'oublier de lier table1 à n'importe quoi (parce que la table "pilote" n'a pas de clause "on"), mais c'est légal.


Sur une jointure interne, ils signifient la même chose. Cependant, vous obtiendrez des résultats différents dans une jointure externe en fonction de si vous mettez la condition de jointure dans la clause WHERE par rapport à la clause ON. Jetez un oeil à cette question connexe et cette réponse (par moi).

Je pense qu'il est plus logique d'avoir toujours l'habitude de placer la condition de jointure dans la clause ON (à moins qu'il s'agisse d'une jointure externe et que vous le vouliez dans la clause where) car cela clarifie la lecture de votre requête à quelles conditions les tables sont jointes, et aussi cela empêche la clause WHERE d'être des dizaines de lignes.


c'est ma solution.

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

Vous devez avoir le GROUP BY pour le faire fonctionner.

J'espère que cette aide.


Cet article explique clairement la différence. Il explique également le "ON joint_condition vs WHERE joint_condition ou joint_alias est null".

La clause WHERE filtre à la fois le côté gauche et le côté droit du JOIN, tandis que la clause ON filtre toujours le côté droit uniquement.

  1. Si vous voulez toujours récupérer les lignes du côté gauche et que JOIN si une condition correspond, alors vous devriez avoir la clause ON.
  2. Si vous souhaitez filtrer le produit de la jonction des deux côtés, vous devez utiliser la clause WHERE.

  • Peu importe pour les jointures internes
  • Questions pour les jointures externes

    une. Clause WHERE : après avoir rejoint. Les enregistrements seront filtrés après que la jointure ait eu lieu.

    b. Clause ON - Avant de rejoindre. Les enregistrements (de la table de droite) seront filtrés avant de rejoindre. Cela peut finir comme nul dans le résultat (depuis la jointure OUTER).



Exemple : Considérez les tableaux ci-dessous:

    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) Dans la clause 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) Dans la clause 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 | 




on-clause