Quali sono gli utilizzi di Cross Join?


105

Un cross join esegue un prodotto cartesiano sulle tuple dei due insiemi.

SELECT *
FROM Table1
CROSS JOIN Table2

Quali circostanze rendono particolarmente utile tale operazione SQL?


36
È davvero triste che questa domanda sia stata chiusa. Penso che potrebbe essere contrassegnato come Community Wiki, ma dire che non è costruttivo è ingiusto.
Wayne Koorts,

1
Sono d'accordo. Questo ha risposto alla domanda esatta che avevo.
Ade

10
Ci sono momenti in cui uno sviluppatore più recente ha difficoltà a comprendere le implicazioni di alcune funzioni del software che sta utilizzando. Domande come questa sono particolarmente utili per gli sviluppatori più recenti, principalmente perché la discussione che segue illumina molte possibilità che lo sviluppatore junior non ha mai considerato. Il formato della domanda è elementare, nella migliore delle ipotesi, ma l'intento sembra essere onesto in quanto si chiede "perché esiste?" Sono d'accordo con Wayne Koorts, è un peccato che casperOne abbia scelto di chiudere questo e lo abbia definito "non costruttivo". La parte "non costruttiva" mi infastidisce particolarmente.
Kaorie

Risposte:


93

Se hai una "griglia" che desideri popolare completamente, come le informazioni sulla taglia e sul colore per un particolare articolo di abbigliamento:

select 
    size,
    color
from
    sizes CROSS JOIN colors

Forse vuoi una tabella che contenga una riga per ogni minuto della giornata e vuoi usarla per verificare che una procedura sia stata eseguita ogni minuto, quindi potresti incrociare tre tabelle:

select
    hour,
    minute
from
    hours CROSS JOIN minutes

Oppure disponi di una serie di specifiche di rapporto standard che desideri applicare ogni mese dell'anno:

select
    specId,
    month
from
    reports CROSS JOIN months

Il problema con il mantenimento di questi come punti di vista è che nella maggior parte dei casi non si desidera un prodotto completo, in particolare per quanto riguarda i vestiti. Puoi aggiungere MINUSlogica alla query per rimuovere determinate combinazioni che non porti, ma potresti trovare più semplice popolare una tabella in un altro modo e non utilizzare un prodotto cartesiano.

Inoltre, potresti finire per provare il cross join su tabelle che hanno forse qualche riga in più di quanto pensavi, o forse la tua WHEREclausola era parzialmente o completamente mancante. In tal caso, il tuo DBA ti avviserà tempestivamente dell'omissione. Di solito lui o lei non saranno felici.


5
... In tal caso, il tuo DBA ti avviserà tempestivamente dell'omissione. Di solito lui o lei non saranno felici. ... haha, così vero!
RSW

2
@ Dave: il secondo esempio non durerà solo un'ora CROSS JOIN minuti?
Rakesh

@ Rakesh, buona presa, stavo pensando a qualcosa di diverso da quello che stavo digitando. Fisso.
Dave DuPlantis

1
Posso immaginare un cross join molto pratico se ti venissero dati 2 set di ID (forse in formato csv), un set conterrebbe gli ID dei dipendenti e l'altro conterrebbe gli ID delle attività. L'idea è che tu abbia una tabella M2M per EmployeeTask. È possibile utilizzare il cross join per assegnare ogni attività data a ogni dipendente, ammesso che tu abbia trasformato il csv in variabili di tabella (o qualcosa del genere).
SynBiotik


14

In genere non vorrai un prodotto cartesiano completo per la maggior parte delle query di database. L'intera potenza dei database relazionali è che puoi applicare qualsiasi restrizione a cui potresti essere interessato per evitare di estrarre righe non necessarie dal database.

Suppongo che un esempio artificioso in cui potresti volerlo è se hai una tabella di dipendenti e una tabella di lavori che devono essere svolti e vuoi vedere tutte le possibili assegnazioni di un dipendente a un lavoro.


11

Ok, questo probabilmente non risponderà alla domanda, ma, se è vero (e non ne sono nemmeno sicuro) è un po 'divertente di storia.

Agli albori di Oracle, uno degli sviluppatori si rese conto che aveva bisogno di duplicare ogni riga di una tabella (ad esempio, è possibile che fosse una tabella di eventi e aveva bisogno di cambiarla separatamente "evento di inizio" e "evento di fine" inserimenti). Si rese conto che se avesse avuto una tabella con solo due righe, avrebbe potuto fare un cross join, selezionando solo le colonne nella prima tabella, e ottenere esattamente ciò di cui aveva bisogno. Così creò un semplice tavolo, che naturalmente chiamò "DUAL".

Successivamente, ha bisogno di fare qualcosa che può essere fatto solo tramite una selezione da una tabella, anche se l'azione in sé non ha nulla a che fare con la tabella, (forse ha dimenticato l'orologio e voleva leggere l'ora tramite SELEZIONA SYSDATE DA .. .) Si rese conto che aveva ancora il suo tavolo DUAL in giro e lo usò. Dopo un po 'si è stancato di vedere l'ora stampata due volte, quindi ha cancellato una delle righe.

Altri in Oracle hanno iniziato a utilizzare la sua tabella e alla fine si è deciso di includerla nell'installazione Oracle standard.

Il che spiega perché una tabella il cui unico significato è che ha una riga ha un nome che significa "due".


8

La chiave è "mostrami tutte le combinazioni possibili". Li ho usati insieme ad altri campi calcolati e poi ordinati / filtrati.

Ad esempio, supponi di creare un'applicazione di arbitraggio (trading). Hai venditori che offrono prodotti a un prezzo e acquirenti che chiedono prodotti a un costo. Esegui un cross join sulla chiave del prodotto (per abbinare i potenziali acquirenti e venditori), calcola lo spread tra costo e prezzo, quindi ordina desc. su questo per darti (l'intermediario) le operazioni più redditizie da eseguire. Quasi sempre avrai ovviamente altri criteri di filtro di delimitazione.


Ah! Questa spiegazione ha più senso per me. In questo caso, un INNER JOIN non ha senso perché non esiste alcuna relazione tra un ID prodotto e un venditore, poiché più venditori possono vendere lo stesso prodotto.
moonman239

3

Accetta qualcosa come una tabella di cifre, che ha dieci righe per le cifre da 0 a 9. Puoi utilizzare il cross join su quella tabella alcune volte per ottenere un risultato che abbia comunque molte righe di cui hai bisogno, con i risultati numerati in modo appropriato. Questo ha una serie di usi. Ad esempio, puoi combinarlo con una funzione datadd () per ottenere un set per ogni giorno in un dato anno.



1

Immagina di avere una serie di domande che desideri inviare su una specifica combinazione di articoli e date (prezzi, disponibilità, ecc.). È possibile caricare gli elementi e le date in tabelle temporanee separate e fare in modo che le query si uniscano alle tabelle. Questo può essere più conveniente dell'alternativa di enumerare gli elementi e le date nelle clausole IN, soprattutto perché alcuni database limitano il numero di elementi in una clausola IN.


1

puoi usarlo CROSS JOIN per: - generare dati a scopo di test - combinare tutte le proprietà - hai bisogno di tutte le possibili combinazioni di eg gruppi sanguigni (A, B, ..) con Rh - / +, ecc ... - sintonizzarlo per i tuoi scopi;) - Non sono esperto in questo settore;)

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;
  • crea un join per 2 tabelle senza un ID comune e poi raggruppalo usando max (), ecc. per trovare la combinazione più alta possibile
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.