Une jointure croisée réalise un produit cartésien sur les tuples des deux ensembles.
SELECT *
FROM Table1
CROSS JOIN Table2
Quelles circonstances rendent une telle opération SQL particulièrement utile?
Si vous avez une "grille" que vous souhaitez remplir complètement, comme des informations de taille et de couleur pour un article de vêtement particulier:
select
size,
color
from
sizes CROSS JOIN colors
Vous souhaitez peut-être une table qui contient une ligne pour chaque minute de la journée, et vous souhaitez l'utiliser pour vérifier qu'une procédure a été exécutée chaque minute, vous pouvez donc traverser trois tables:
select
hour,
minute
from
hours CROSS JOIN minutes
Ou vous disposez d'un ensemble de spécifications de rapport standard que vous souhaitez appliquer à chaque mois de l'année:
select
specId,
month
from
reports CROSS JOIN months
Le problème avec le maintien de ces vues est que dans la plupart des cas, vous ne voulez pas d'un produit complet, en particulier en ce qui concerne les vêtements. Vous pouvez ajouter une logique MINUS
à la requête pour supprimer certaines combinaisons que vous ne portez pas, mais vous trouverez peut-être plus facile de remplir un tableau d'une autre manière et de ne pas utiliser de produit cartésien.
En outre, vous pourriez finir par essayer la jointure croisée sur des tables qui ont peut-être quelques lignes de plus que vous ne le pensiez, ou peut-être que votre clause WHERE
était partiellement ou complètement manquante. Dans ce cas, votre DBA vous informera rapidement de l'omission. Habituellement, il ne sera pas content.
Vous ne voudrez généralement pas de produit cartésien complet pour la plupart des requêtes de base de données. Toute la puissance des bases de données relationnelles est que vous pouvez appliquer toutes les restrictions qui pourraient vous intéresser pour vous permettre d'éviter de tirer des lignes inutiles de la base de données.
Je suppose qu'un exemple artificiel où vous voudrez peut-être, c'est si vous avez une table des employés et une table des emplois à faire et que vous voulez voir toutes les affectations possibles d'un employé à un emploi.
Générez des données pour les tests.
D'accord, cela ne répondra probablement pas à la question, mais, si c'est vrai (et je n'en suis même pas sûr), c'est un peu d'histoire amusante.
Dans les premiers jours d'Oracle, l'un des développeurs s'est rendu compte qu'il devait dupliquer chaque ligne d'une table (par exemple, il était possible que ce soit une table d'événements et qu'il devait la changer séparément "événement de début" et "événement de fin" entrées). Il a réalisé que s'il avait une table avec seulement deux lignes, il pourrait faire une jointure croisée, en sélectionnant uniquement les colonnes dans la première table, et obtenir exactement ce dont il avait besoin. Il a donc créé une table simple, qu'il a naturellement appelée "DUAL".
Plus tard, il doit faire quelque chose qui ne peut être fait que via une sélection dans une table, même si l'action elle-même n'a rien à voir avec la table, (peut-être qu'il a oublié sa montre et voulait lire l'heure via SELECT SYSDATE FROM .. .) Il a réalisé qu'il avait toujours sa table DUAL traîner, et l'a utilisé. Après un certain temps, il en avait assez de voir l'heure imprimée deux fois, alors il a finalement supprimé l'une des lignes.
D'autres chez Oracle ont commencé à utiliser sa table, et finalement, il a été décidé de l'inclure dans l'installation Oracle standard.
Ce qui explique pourquoi une table dont la seule signification est qu'elle a une ligne a un nom qui signifie "deux".
La clé est "montrez-moi toutes les combinaisons possibles". Je les ai utilisés conjointement avec d'autres champs calculés et ensuite triés/filtrés.
Par exemple, supposons que vous construisez une application d'arbitrage (trading). Vous avez des vendeurs qui proposent des produits à un prix et des acheteurs qui demandent des produits à un prix. Vous effectuez une jointure croisée sur la clé de produit (pour faire correspondre les acheteurs et les vendeurs potentiels), calculez l'écart entre le coût et le prix, puis triez desc. à ce sujet pour vous (l'intermédiaire) les métiers les plus rentables à exécuter. Bien entendu, vous aurez presque toujours d'autres critères de filtre englobant.
Prend quelque chose comme une table de chiffres, qui a dix lignes pour les chiffres de 0 à 9. Vous pouvez utiliser la jointure croisée sur cette table plusieurs fois pour obtenir un résultat contenant le nombre de lignes dont vous avez besoin, les résultats étant numérotés de manière appropriée. Cela a un certain nombre d'utilisations. Par exemple, vous pouvez la combiner avec une fonction datadd () pour obtenir un ensemble pour chaque jour d'une année donnée.
C'est une façon intéressante d'utiliser une jointure croisée pour créer un rapport d'analyse croisée . Je l'ai trouvé dans SQL For Smarties de Joe Celko , et je l'ai utilisé plusieurs fois. Cela prend un peu de configuration, mais cela vaut le temps investi.
Imaginez que vous vouliez émettre une série de requêtes sur une combinaison spécifique d'articles et de dates (prix, disponibilité, etc.). Vous pouvez charger les éléments et les dates dans des tables temporaires distinctes et faire croiser vos requêtes avec les tables. Cela peut être plus pratique que l'alternative d'énumérer les éléments et les dates dans les clauses IN, d'autant plus que certaines bases de données limitent le nombre d'éléments dans une clause IN.
vous pouvez l'utiliser CROSS JOIN pour: - générer des données à des fins de test - combiner toutes les propriétés - vous avez besoin de toutes les combinaisons possibles, par exemple de groupes sanguins (A, B, ..) avec Rh -/+, etc. ... - ajustez-le pour vos besoins;) - Je ne suis pas expert dans ce domaine;)
CREATE TABLE "HR"."BL_GRP_01"
("GR_1" VARCHAR2(5 BYTE));
REM INSERTING into BL_GRP_01
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_01 (GR_1) values (NULL);
CREATE TABLE "HR"."BL_GRP_02"
("GR_1" VARCHAR2(5 BYTE));
REM INSERTING into BL_GRP_02
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_02 (GR_1) values (NULL);
CREATE TABLE "HR"."RH_VAL_01"
("RH_VAL" VARCHAR2(5 BYTE));
REM INSERTING into RH_VAL_01
SET DEFINE OFF;
Insert into RH_VAL_01 (RH_VAL) values ('+');
Insert into RH_VAL_01 (RH_VAL) values ('-');
Insert into RH_VAL_01 (RH_VAL) values (NULL);
select distinct a.GR_1 || b.GR_1 || c.RH_VAL as BL_GRP
from BL_GRP_01 a, BL_GRP_02 b, RH_VAL_01 c
GROUP BY a.GR_1, b.GR_1, c.RH_VAL;