Question

Une jointure croisée effectue un produit cartésien sur les nuplets des deux jeux.

SELECT *
FROM Table1
CROSS JOIN Table2

Quelles circonstances rendent une telle opération SQL particulièrement utile?

Était-ce utile?

La solution

Si vous avez une "grille" que vous voulez renseigner complètement, comme les informations de taille et de couleur pour un vêtement particulier:

select 
    size,
    color
from
    sizes CROSS JOIN colors

Peut-être souhaitez-vous une table contenant une ligne pour chaque minute de la journée et que vous souhaitez l'utiliser pour vérifier qu'une procédure a été exécutée toutes les minutes; vous pouvez donc parcourir trois tables:

select
    hour,
    minute
from
    hours CROSS JOIN minutes

Vous pouvez également appliquer un ensemble de spécifications de rapport standard à chaque mois de l'année:

select
    specId,
    month
from
    reports CROSS JOIN months

Le problème avec le maintien de ces vues en vue est que dans la plupart des cas, vous ne voulez pas un produit complet, en particulier en ce qui concerne les vêtements. Vous pouvez ajouter la logique MOINS à la requête pour supprimer certaines combinaisons que vous ne transportez pas, mais vous pouvez trouver plus facile de remplir une table d'une autre manière et de ne pas utiliser de produit cartésien.

De plus, vous pourriez éventuellement essayer de joindre les deux parties sur des tables contenant 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 cette omission. Habituellement, il ne sera pas heureux.

Autres conseils

En règle générale, vous ne souhaiterez pas un produit cartésien complet pour la plupart des requêtes de base de données. Toute la puissance des bases de données relationnelles réside dans le fait que vous pouvez appliquer toutes les restrictions qui pourraient vous intéresser pour éviter de tirer des lignes inutiles de la base de données.

Je suppose que vous voudrez peut-être un exemple artificiel si vous disposez d'un tableau des employés et d'un tableau des tâches qui doivent être effectuées et que vous souhaitez voir toutes les affectations possibles d'un employé à un seul travail.

Générer 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 amusant l'histoire.

Aux débuts d’Oracle, l’un des développeurs comprit qu’il devait dupliquer chaque ligne d’un tableau (par exemple, il était possible qu’il s’agisse d’un tableau d’événements et il fallait le modifier séparément, "Démarrer l’événement" et "entrées de fin d'événement". Il s'est rendu compte que s'il avait une table avec seulement deux rangées, il pourrait faire une jointure croisée en sélectionnant uniquement les colonnes de la première table et obtenir exactement ce dont il avait besoin. Il a donc créé un tableau simple, qu’il a assez naturellement appelé "DUAL".

Plus tard, il doit faire quelque chose qui ne peut être fait que via une sélection à partir d’une table, même si l’action n’a rien à voir avec la table (il a peut-être oublié sa montre et voulait lire l’heure via SELECT SYSDATE FROM ...) Il réalisa qu'il avait toujours sa table DUAL qui traînait et l'utilisa. Au bout d’un moment, il en avait assez de voir le temps imprimé deux fois, il a donc supprimé l’un des rangs.

D'autres personnes chez Oracle ont commencé à utiliser sa table et, finalement, il a été décidé de l'inclure dans l'installation standard d'Oracle.

Ce qui explique pourquoi une table dont le seul sens est qu’elle a une ligne a un nom qui signifie "deux".

La clé est "montre-moi toutes les combinaisons possibles". Je les ai utilisés avec d'autres champs calculés puis triés / filtrés.

Par exemple, supposons que vous construisez une application d'arbitrage (trading). Vous avez des vendeurs proposant des produits à un prix et des acheteurs demandant des produits à un coût. Vous faites 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. sur cela pour vous donner (le intermédiaire) les métiers les plus rentables à exécuter. Presque toujours, vous aurez bien sûr d’autres critères de filtrage limitatifs.

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 plusieurs fois sur cette table pour obtenir un résultat contenant le nombre de lignes souhaité, avec les résultats numérotés de manière appropriée. Cela a un certain nombre d'utilisations. Par exemple, vous pouvez le combiner avec une fonction datadd () pour obtenir un ensemble pour chaque jour d'une année donnée.

C’est un moyen intéressant d’utiliser une jointure croisée avec créer un rapport d'analyse croisée . Je l'ai trouvé dans le Le code SQL de Smarty de Joe Celko , et je l'ai utilisé plusieurs fois. Cela prend un peu de temps, mais ça vaut le temps investi.

Imaginez que vous souhaitiez émettre une série de questions portant sur une combinaison d'éléments et de dates (prix, disponibilité, etc.). Vous pouvez charger les éléments et les dates dans des tables temporaires distinctes et faire en sorte que vos requêtes se joignent aux tables. Cela peut être plus pratique que l’alternative consistant à é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 - combinez toutes les propriétés - vous avez besoin de toutes les combinaisons possibles, par exemple, de groupes sanguins (A, B, ..) avec Rh - / +, etc ... - adaptez-le à vos besoins;) - Je ne suis pas un 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;
  • créez une jointure pour 2 tables sans identifiant commun, puis regroupez-la à l'aide de max (), etc.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top