Domanda

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

SELECT *
FROM Table1
CROSS JOIN Table2

Quali circostanze rendono particolarmente utile tale operazione SQL?

È stato utile?

Soluzione

Se disponi di una "griglia" che vuoi popolare completamente, come le informazioni su taglia e colore per un particolare capo di abbigliamento:

select 
    size,
    color
from
    sizes CROSS JOIN colors

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

select
    hour,
    minute
from
    hours CROSS JOIN minutes

Oppure hai una serie di specifiche standard per i rapporti che desideri applicare ogni mese dell'anno:

select
    specId,
    month
from
    reports CROSS JOIN months

Il problema di mantenerli 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 la logica MINUS alla query per rimuovere alcune combinazioni che non porti, ma potresti trovare più facile popolare una tabella in un altro modo e non usare un prodotto cartesiano.

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

Altri suggerimenti

In genere non si desidera un prodotto cartesiano completo per la maggior parte delle query del database. L'intero potere dei database relazionali è che puoi applicare qualsiasi limitazione ti possa interessare per permetterti di evitare di estrarre le righe non necessarie dal db.

Suppongo che un esempio inventato in cui potresti desiderare sia se hai una tabella di dipendenti e una tabella di lavori che devono essere eseguiti e vuoi vedere tutti i possibili incarichi di un dipendente per un lavoro.

Genera dati per i test.

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

All'inizio di Oracle, uno degli sviluppatori si rese conto che aveva bisogno di duplicare ogni riga in una tabella (per esempio, è possibile che fosse una tabella di eventi e che avesse bisogno di cambiarla separatamente "start event" e "end end" (voci). Si rese conto che se avesse avuto una tabella con solo due righe, avrebbe potuto fare un join incrociato, selezionando solo le colonne nella prima tabella e ottenere esattamente se ne avesse avuto bisogno. Quindi ha creato una tabella semplice, che ha chiamato abbastanza naturalmente "DUAL".

In seguito, deve fare qualcosa che può essere fatto solo tramite una selezione da un tavolo, anche se l'azione stessa non ha nulla a che fare con il tavolo (forse ha dimenticato l'orologio e voleva leggere l'ora tramite SELECT SYSDATE DA ...) Si rese conto di avere ancora il suo tavolo DUAL in giro, e lo usò. Dopo un po ', si stancò di vedere il tempo stampato due volte, quindi alla fine cancellò una delle file.

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

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

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

Ad esempio, supponiamo che tu stia creando un'applicazione di arbitraggio (trading). Hai venditori che offrono prodotti a un prezzo e acquirenti che chiedono prodotti a un costo. Fai un cross join sul codice Product Key (per abbinare potenziali acquirenti e venditori), calcola lo spread tra costo e prezzo, quindi ordina la descrizione. su questo per darti (l'intermediario) le operazioni più redditizie da eseguire. Quasi sempre avrai ovviamente altri criteri di filtro limite.

Prende qualcosa come una tabella di cifre, che ha dieci righe per le cifre 0-9. È possibile utilizzare il join incrociato su quella tabella alcune volte per ottenere un risultato che contenga quante righe siano necessarie, 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 determinato anno.

Questo è un modo interessante di usare un cross join per crea un rapporto a campi incrociati . L'ho trovato in SQL For Smarties di Joe Celko e l'ho usato più volte. Ci vuole un po 'di installazione, ma è valsa la pena spendere tempo.

Immagina di avere una serie di domande che desideri inviare su una specifica combinazione di articoli e date (prezzi, disponibilità, ecc.). È possibile caricare gli articoli 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, specialmente perché alcuni database limitano il numero di elementi in una clausola IN.

puoi usarlo CROSS JOIN per: - generare dati a scopo di test - combina tutte le proprietà - hai bisogno di tutte le possibili combinazioni di gruppi sanguigni (A, B, ..) con Rh - / +, ecc ... - sintonizzalo 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 utilizzando max (), ecc. per trovare la combinazione più alta possibile
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top