55 votes

Quelle est la différence entre l'utilisation d'une jointure croisée et l'insertion d'une virgule entre les deux tables ?

Quelle est la différence entre

select * from A, B

y

select * from A cross join B

? Ils semblent donner les mêmes résultats.

La deuxième version est-elle préférée à la première ? La première version est-elle complètement erronée sur le plan syntaxique ?

1 votes

Les produits cartésiens ne sont presque jamais utiles...

12 votes

Mais dans les rares cas où ils le sont, il est bon de savoir comment les écrire.

3 votes

Rarement utile, mais existe probablement au moins une fois dans chaque grand projet.

55voto

OMG Ponies Points 144785

Ils renvoient les mêmes résultats car ils sont sémantiquement identiques. Ceci :

select * 
  from A, B

...est la syntaxe ANSI-89. Sans clause WHERE pour relier les tables entre elles, le résultat est un produit cartésien. Ce qui est exactement ce qu'Alternative fournit également :

    select * 
      from A 
cross join B

...mais le CROSS JOIN est une syntaxe ANSI-92.

À propos de la performance

Il n'y a pas de différence de performance entre eux.

Pourquoi utiliser la norme ANSI-92 ?

La raison d'utiliser la syntaxe ANSI-92 est la prise en charge des JOINTS EXTERNES (IE : LEFT, FULL, RIGHT) - la syntaxe ANSI-89 n'en comporte pas, de sorte que de nombreuses bases de données ont implémenté leur propre syntaxe (qui n'est pas transférable à d'autres bases de données). IE : Oracle's (+) , le système d'information de SQL Server =*

16voto

Me.Name Points 3103

Je suis tombé sur ce post à partir d'une autre question sur le SO, mais la grande différence est le lien que crée la jonction transversale. Par exemple, en utilisant cross apply ou une autre jointure après B dans la première variante ("virgule"), l'application croisée ou la jointure ne se réfère qu'au(x) tableau(x) situé(s) après le point. par exemple, ce qui suit :

select * from A, B join C on C.SomeField = A.SomeField and C.SomeField = B.SomeField 

provoquerait une erreur :

L'identifiant en plusieurs parties "A.SomeField" n'a pas pu être lié.

parce que la jointure sur C ne concerne que B, alors que c'est la même chose avec la jointure croisée...

select * from A cross join B join C on C.SomeField = A.SomeField and C.SomeField = B.SomeField 

est jugée acceptable. Il en va de même si cross apply est utilisé. Par exemple, le fait de placer une croix d'application sur une fonction après B La fonction ne peut utiliser que des champs de B, alors que la même requête avec jointure croisée peut utiliser des champs de A et de B. Bien entendu, l'inverse est également possible. Si vous souhaitez ajouter une jointure uniquement pour l'une des tables, vous pouvez le faire en utilisant la virgule sur les tables.

14voto

Paul Draper Points 14352

Outre la brièveté (en favorisant , ) et la cohérence (favoriser CROSS JOIN ), la seule différence est la préséance.

La virgule a une priorité inférieure à celle des autres jointures.


Par exemple, la forme explicite de

SELECT *
FROM a
  CROSS JOIN b
  JOIN c ON a.id = c.id

est

SELECT *
FROM (
  a
  CROSS JOIN b
)
  INNER JOIN c ON a.id = c.id

qui est valide.

Alors que la forme explicite de

SELECT *
FROM a,
  b
  JOIN c ON a.id = c.id

est

SELECT *
FROM a
  CROSS JOIN (
    b
    INNER JOIN c ON a.id = c.id
  )

qui n'est pas valide (la clause de jonction fait référence à des données inaccessibles). a ).


Dans votre exemple, il n'y a que deux tables, les deux requêtes sont donc exactement équivalentes.

6voto

Otávio Décio Points 44200

Ils sont identiques et ne devraient (presque) jamais être utilisés.

0 votes

Mais si vous faire doivent les recouper, veuillez utiliser cette dernière :-) Il est tout à fait idiot que la jonction croisée ait reçu cette notation raccourcie.

3 votes

Je pense que la "notation de raccourci" est antérieure à la notation de jointure croisée.

2 votes

Vous avez raison CROSS JOIN est devenue la norme ANSI dans SQL:1992, par opposition à la syntaxe ANSI SQL:1989 utilisant des virgules.

3voto

Mark Byers Points 318575

La première version était à l'origine le seul moyen de joindre deux tables. Mais elle présente un certain nombre de problèmes, si bien que le mot-clé JOIN a été ajouté dans la norme ANSI-92. Les deux versions donnent les mêmes résultats, mais la seconde est plus explicite et doit être préférée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X