Mysql
 sql >> Database >  >> RDS >> Mysql

La query SQL restituisce dati da più tabelle

Parte 1 - Unioni e unioni

Questa risposta copre:

  1. Parte 1
  2. Parte 2
    • Subquery:cosa sono, dove possono essere utilizzate e a cosa prestare attenzione
    • Il cartesiano si unisce ad AKA - Oh, che miseria!

Esistono diversi modi per recuperare i dati da più tabelle in un database. In questa risposta, utilizzerò la sintassi di join ANSI-92. Questo potrebbe essere diverso da una serie di altri tutorial là fuori che usano la vecchia sintassi ANSI-89 (e se sei abituato a 89, può sembrare molto meno intuitivo, ma tutto quello che posso dire è di provarlo) poiché è molto più facile da capire quando le query iniziano a diventare più complesse. Perché usarlo? C'è un aumento delle prestazioni? La risposta breve è no, ma è più facile da leggere una volta che ci si abitua. È più facile leggere le query scritte da altre persone usando questa sintassi.

Userò anche il concetto di un piccolo deposito automobilistico che ha un database per tenere traccia di quali auto ha a disposizione. Il proprietario ti ha assunto come suo addetto al computer IT e si aspetta che tu possa lasciargli i dati che chiede in un attimo.

Ho creato una serie di tabelle di ricerca che verranno utilizzate dal tavolo finale. Questo ci darà un modello ragionevole su cui lavorare. Per iniziare, eseguirò le mie query su un database di esempio che ha la struttura seguente. Cercherò di pensare agli errori comuni che vengono commessi all'inizio e di spiegare cosa c'è di sbagliato in essi, oltre ovviamente a mostrare come correggerli.

La prima tabella è semplicemente un elenco di colori in modo da sapere quali colori abbiamo nel cortile dell'auto.

mysql> create table colors(id int(3) not null auto_increment primary key, 
    -> color varchar(15), paint varchar(10));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from colors;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| color | varchar(15) | YES  |     | NULL    |                |
| paint | varchar(10) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql> insert into colors (color, paint) values ('Red', 'Metallic'), 
    -> ('Green', 'Gloss'), ('Blue', 'Metallic'), 
    -> ('White' 'Gloss'), ('Black' 'Gloss');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from colors;
+----+-------+----------+
| id | color | paint    |
+----+-------+----------+
|  1 | Red   | Metallic |
|  2 | Green | Gloss    |
|  3 | Blue  | Metallic |
|  4 | White | Gloss    |
|  5 | Black | Gloss    |
+----+-------+----------+
5 rows in set (0.00 sec)

La tabella dei marchi identifica le diverse marche delle auto che il cantiere potrebbe vendere.

mysql> create table brands (id int(3) not null auto_increment primary key, 
    -> brand varchar(15));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from brands;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| brand | varchar(15) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> insert into brands (brand) values ('Ford'), ('Toyota'), 
    -> ('Nissan'), ('Smart'), ('BMW');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from brands;
+----+--------+
| id | brand  |
+----+--------+
|  1 | Ford   |
|  2 | Toyota |
|  3 | Nissan |
|  4 | Smart  |
|  5 | BMW    |
+----+--------+
5 rows in set (0.00 sec)

La tabella dei modelli coprirà diversi tipi di auto, sarà più semplice utilizzare diversi tipi di auto piuttosto che modelli di auto reali.

mysql> create table models (id int(3) not null auto_increment primary key, 
    -> model varchar(15));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from models;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| model | varchar(15) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> insert into models (model) values ('Sports'), ('Sedan'), ('4WD'), ('Luxury');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from models;
+----+--------+
| id | model  |
+----+--------+
|  1 | Sports |
|  2 | Sedan  |
|  3 | 4WD    |
|  4 | Luxury |
+----+--------+
4 rows in set (0.00 sec)

E infine, per legare tutti questi altri tavoli, il tavolo che lega tutto insieme. Il campo ID è in realtà il numero di lotto univoco utilizzato per identificare le auto.

mysql> create table cars (id int(3) not null auto_increment primary key, 
    -> color int(3), brand int(3), model int(3));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from cars;
+-------+--------+------+-----+---------+----------------+
| Field | Type   | Null | Key | Default | Extra          |
+-------+--------+------+-----+---------+----------------+
| id    | int(3) | NO   | PRI | NULL    | auto_increment |
| color | int(3) | YES  |     | NULL    |                |
| brand | int(3) | YES  |     | NULL    |                |
| model | int(3) | YES  |     | NULL    |                |
+-------+--------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> insert into cars (color, brand, model) values (1,2,1), (3,1,2), (5,3,1), 
    -> (4,4,2), (2,2,3), (3,5,4), (4,1,3), (2,2,1), (5,2,3), (4,5,1);
Query OK, 10 rows affected (0.00 sec)
Records: 10  Duplicates: 0  Warnings: 0

mysql> select * from cars;
+----+-------+-------+-------+
| id | color | brand | model |
+----+-------+-------+-------+
|  1 |     1 |     2 |     1 |
|  2 |     3 |     1 |     2 |
|  3 |     5 |     3 |     1 |
|  4 |     4 |     4 |     2 |
|  5 |     2 |     2 |     3 |
|  6 |     3 |     5 |     4 |
|  7 |     4 |     1 |     3 |
|  8 |     2 |     2 |     1 |
|  9 |     5 |     2 |     3 |
| 10 |     4 |     5 |     1 |
+----+-------+-------+-------+
10 rows in set (0.00 sec)

Questo ci fornirà dati sufficienti (spero) per coprire gli esempi seguenti di diversi tipi di join e anche fornire dati sufficienti per renderli utili.

Quindi, entrando nel merito, il capo vuole sapere Gli ID di tutte le auto sportive che possiede .

Questo è un semplice join di due tabelle. Abbiamo una tabella che identifica il modello e la tabella con lo stock disponibile al suo interno. Come puoi vedere, i dati nel model colonna delle cars la tabella si riferisce ai models colonna delle cars tavolo che abbiamo. Ora sappiamo che la tabella dei modelli ha un ID di 1 per Sports quindi scriviamo il join.

select
    ID,
    model
from
    cars
        join models
            on model=ID

Quindi questa query sembra buona, giusto? Abbiamo identificato le due tabelle e contengono le informazioni di cui abbiamo bisogno e utilizziamo un join che identifica correttamente su quali colonne unirci.

ERROR 1052 (23000): Column 'ID' in field list is ambiguous

Oh no! Un errore nella nostra prima query! Sì, ed è una prugna. Vedete, la query ha effettivamente le colonne giuste, ma alcune di esse esistono in entrambe le tabelle, quindi il database si confonde su quale colonna effettiva intendiamo e dove. Ci sono due soluzioni per risolvere questo problema. Il primo è carino e semplice, possiamo usare tableName.columnName per dire al database esattamente cosa intendiamo, in questo modo:

select
    cars.ID,
    models.model
from
    cars
        join models
            on cars.model=models.ID

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  3 | Sports |
|  8 | Sports |
| 10 | Sports |
|  2 | Sedan  |
|  4 | Sedan  |
|  5 | 4WD    |
|  7 | 4WD    |
|  9 | 4WD    |
|  6 | Luxury |
+----+--------+
10 rows in set (0.00 sec)

L'altro è probabilmente usato più spesso e si chiama table aliasing. Le tabelle in questo esempio hanno nomi semplici e brevi, ma digitando qualcosa come KPI_DAILY_SALES_BY_DEPARTMENT probabilmente invecchierebbe rapidamente, quindi un modo semplice è dare un soprannome al tavolo in questo modo:

select
    a.ID,
    b.model
from
    cars a
        join models b
            on a.model=b.ID

Ora, torniamo alla richiesta. Come puoi vedere, abbiamo le informazioni di cui abbiamo bisogno, ma abbiamo anche informazioni che non sono state richieste, quindi dobbiamo includere una clausola dove nella dichiarazione per ottenere le auto sportive solo come richiesto. Poiché preferisco il metodo dell'alias di tabella piuttosto che usare i nomi delle tabelle più e più volte, da questo punto in poi mi atterrò ad esso.

Chiaramente, dobbiamo aggiungere una clausola where alla nostra query. Possiamo identificare le auto sportive tramite ID=1 o model='Sports' . Poiché l'ID è indicizzato e la chiave primaria (e sembra essere meno digitata), usiamola nella nostra query.

select
    a.ID,
    b.model
from
    cars a
        join models b
            on a.model=b.ID
where
    b.ID=1

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  3 | Sports |
|  8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)

Bingo! Il capo è felice. Ovviamente, essendo un capo e non essendo mai soddisfatto di ciò che ha chiesto, guarda le informazioni, poi dice Voglio anche i colori .

Ok, quindi abbiamo già scritto una buona parte della nostra query, ma dobbiamo usare una terza tabella che è i colori. Ora, la nostra tabella informativa principale cars memorizza l'ID colore dell'auto e questo si collega alla colonna ID colori. Quindi, in modo simile all'originale, possiamo unire una terza tabella:

select
    a.ID,
    b.model
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
where
    b.ID=1

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  3 | Sports |
|  8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)

Maledizione, sebbene la tabella sia stata unita correttamente e le relative colonne siano state collegate, ci siamo dimenticati di inserire le informazioni effettive dalla nuova tabella che abbiamo appena collegato.

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
where
    b.ID=1

+----+--------+-------+
| ID | model  | color |
+----+--------+-------+
|  1 | Sports | Red   |
|  8 | Sports | Green |
| 10 | Sports | White |
|  3 | Sports | Black |
+----+--------+-------+
4 rows in set (0.00 sec)

Giusto, questo è il capo alle nostre spalle per un momento. Ora, per spiegare alcune di queste cose un po' più in dettaglio. Come puoi vedere, il from La clausola nella nostra istruzione collega la nostra tabella principale (uso spesso una tabella che contiene informazioni piuttosto che una tabella di ricerca o dimensione. La query funzionerebbe altrettanto bene con le tabelle tutte invertite, ma ha meno senso quando torniamo a questa query per leggerlo tra qualche mese, quindi spesso è meglio provare a scrivere una query che sia piacevole e di facile comprensione - disponila in modo intuitivo, usa un bel rientro in modo che tutto sia il più chiaro possibile. continua a insegnare agli altri, cerca di instillare queste caratteristiche nelle loro domande, specialmente se dovrai risolverle.

È del tutto possibile continuare a collegare sempre più tabelle in questo modo.

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1

Anche se ho dimenticato di includere una tabella in cui potremmo voler unire più di una colonna nel join dichiarazione, ecco un esempio. Se i models la tabella aveva modelli specifici del marchio e quindi aveva anche una colonna chiamata brand che si ricollegava ai brands tabella sul ID campo, potrebbe essere fatto in questo modo:

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
            and b.brand=d.ID
where
    b.ID=1

Puoi vedere che la query sopra non solo collega le tabelle unite alle cars principali table, ma specifica anche i join tra le tabelle già unite. Se ciò non è stato fatto, il risultato è chiamato join cartesiano, il che dba parla male. Un join cartesiano è quello in cui vengono restituite le righe perché le informazioni non dicono al database come limitare i risultati, quindi la query restituisce tutto le righe che soddisfano i criteri.

Quindi, per fare un esempio di join cartesiano, eseguiamo la seguente query:

select
    a.ID,
    b.model
from
    cars a
        join models b

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  1 | Sedan  |
|  1 | 4WD    |
|  1 | Luxury |
|  2 | Sports |
|  2 | Sedan  |
|  2 | 4WD    |
|  2 | Luxury |
|  3 | Sports |
|  3 | Sedan  |
|  3 | 4WD    |
|  3 | Luxury |
|  4 | Sports |
|  4 | Sedan  |
|  4 | 4WD    |
|  4 | Luxury |
|  5 | Sports |
|  5 | Sedan  |
|  5 | 4WD    |
|  5 | Luxury |
|  6 | Sports |
|  6 | Sedan  |
|  6 | 4WD    |
|  6 | Luxury |
|  7 | Sports |
|  7 | Sedan  |
|  7 | 4WD    |
|  7 | Luxury |
|  8 | Sports |
|  8 | Sedan  |
|  8 | 4WD    |
|  8 | Luxury |
|  9 | Sports |
|  9 | Sedan  |
|  9 | 4WD    |
|  9 | Luxury |
| 10 | Sports |
| 10 | Sedan  |
| 10 | 4WD    |
| 10 | Luxury |
+----+--------+
40 rows in set (0.00 sec)

Buon Dio, è brutto. Tuttavia, per quanto riguarda il database, è esattamente cosa è stato chiesto. Nella query, abbiamo chiesto l'ID da cars e il model da models . Tuttavia, poiché non abbiamo specificato come per unire le tabelle, il database ha abbinato ogni riga dalla prima tabella con ogni riga dalla seconda tabella.

Ok, quindi il capo è tornato e vuole di nuovo più informazioni. Voglio lo stesso elenco, ma includi anche 4WD .

Questo, tuttavia, ci offre un'ottima scusa per guardare a due modi diversi per raggiungere questo obiettivo. Potremmo aggiungere un'altra condizione alla clausola where come questa:

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1
    or b.ID=3

Anche se quanto sopra funzionerà perfettamente, guardiamo in modo diverso, questa è un'ottima scusa per mostrare come un union la query funzionerà.

Sappiamo che tutte le auto sportive restituiranno:

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1

E quanto segue restituirebbe tutti i 4WD:

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=3

Quindi aggiungendo un union all clausola tra di loro, i risultati della seconda query verranno aggiunti ai risultati della prima query.

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1
union all
select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=3

+----+--------+-------+
| ID | model  | color |
+----+--------+-------+
|  1 | Sports | Red   |
|  8 | Sports | Green |
| 10 | Sports | White |
|  3 | Sports | Black |
|  5 | 4WD    | Green |
|  7 | 4WD    | White |
|  9 | 4WD    | Black |
+----+--------+-------+
7 rows in set (0.00 sec)

Come puoi vedere, vengono restituiti per primi i risultati della prima query, seguiti dai risultati della seconda query.

In questo esempio, sarebbe stato ovviamente molto più semplice utilizzare semplicemente la prima query, ma union le query possono essere ottime per casi specifici. Sono un ottimo modo per restituire risultati specifici da tabelle da tabelle che non possono essere unite tra loro facilmente o, se è per questo, completamente tabelle non correlate. Tuttavia, ci sono alcune regole da seguire.

  • I tipi di colonna della prima query devono corrispondere ai tipi di colonna di ogni altra query seguente.
  • I nomi delle colonne della prima query verranno utilizzati per identificare l'intero set di risultati.
  • Il numero di colonne in ogni query deve essere lo stesso.

Ora, potresti ti starai chiedendo cosa il la differenza sta nell'usare union e union all . Un union la query rimuoverà i duplicati, mentre un union all non lo farà. Ciò significa che si verifica un piccolo calo delle prestazioni quando si utilizza union su union all ma i risultati potrebbero valerne la pena - non speculerò su questo genere di cose in questo però.

Su questa nota, potrebbe valere la pena notare alcune note aggiuntive qui.

  • Se volessimo ordinare i risultati, possiamo utilizzare un order by ma non puoi più usare l'alias. Nella query precedente, aggiungendo un order by a.ID risulterebbe in un errore - per quanto riguarda i risultati, la colonna si chiama ID anziché a.ID - anche se lo stesso alias è stato utilizzato in entrambe le query.
  • Possiamo avere solo un order by istruzione e deve essere l'ultima istruzione.

Per i prossimi esempi, aggiungo alcune righe in più alle nostre tabelle.

Ho aggiunto Holden alla tabella dei marchi. Ho anche aggiunto una riga in cars che ha il color valore di 12 - che non ha riferimento nella tabella dei colori.

Ok, il capo è tornato di nuovo, abbaiando richieste - *Voglio un conteggio di ogni marchio che trasportiamo e il numero di auto in esso contenute!` - Tipico, arriviamo a una sezione interessante della nostra discussione e il capo vuole più lavoro .

Giusto, quindi la prima cosa che dobbiamo fare è ottenere un elenco completo dei possibili marchi.

select
    a.brand
from
    brands a

+--------+
| brand  |
+--------+
| Ford   |
| Toyota |
| Nissan |
| Smart  |
| BMW    |
| Holden |
+--------+
6 rows in set (0.00 sec)

Ora, quando ci uniamo alla nostra tabella delle auto, otteniamo il seguente risultato:

select
    a.brand
from
    brands a
        join cars b
            on a.ID=b.brand
group by
    a.brand

+--------+
| brand  |
+--------+
| BMW    |
| Ford   |
| Nissan |
| Smart  |
| Toyota |
+--------+
5 rows in set (0.00 sec)

Il che ovviamente è un problema:non stiamo vedendo alcuna menzione dell'adorabile Holden marchio che ho aggiunto.

Questo perché un join cerca le righe corrispondenti in entrambi tavoli. Poiché non ci sono dati nelle auto di tipo Holden non viene restituito. Qui è dove possiamo usare un outer giuntura. Questo restituirà tutti i risultati di una tabella indipendentemente dal fatto che siano abbinati nell'altra tabella o meno:

select
    a.brand
from
    brands a
        left outer join cars b
            on a.ID=b.brand
group by
    a.brand

+--------+
| brand  |
+--------+
| BMW    |
| Ford   |
| Holden |
| Nissan |
| Smart  |
| Toyota |
+--------+
6 rows in set (0.00 sec)

Ora che ce l'abbiamo, possiamo aggiungere un'adorabile funzione aggregata per ottenere un conteggio e toglierci di dosso il capo per un momento.

select
    a.brand,
    count(b.id) as countOfBrand
from
    brands a
        left outer join cars b
            on a.ID=b.brand
group by
    a.brand

+--------+--------------+
| brand  | countOfBrand |
+--------+--------------+
| BMW    |            2 |
| Ford   |            2 |
| Holden |            0 |
| Nissan |            1 |
| Smart  |            1 |
| Toyota |            5 |
+--------+--------------+
6 rows in set (0.00 sec)

E con questo, via il capo si intrufola.

Ora, per spiegare questo in modo più dettagliato, i join esterni possono essere di left o right genere. Sinistra o Destra definisce quale tabella è completamente incluso. Un left outer join includerà tutte le righe della tabella a sinistra, mentre (hai indovinato) un right outer join porta tutti i risultati della tabella a destra nei risultati.

Alcuni database consentiranno un full outer join che riporterà i risultati (corrispondenti o meno) da entrambi tabelle, ma questo non è supportato in tutti i database.

Ora, probabilmente immagino che a questo punto ti stai chiedendo se puoi o meno unire i tipi di join in una query - e la risposta è sì, puoi assolutamente farlo.

select
    b.brand,
    c.color,
    count(a.id) as countOfBrand
from
    cars a
        right outer join brands b
            on b.ID=a.brand
        join colors c
            on a.color=c.ID
group by
    a.brand,
    c.color

+--------+-------+--------------+
| brand  | color | countOfBrand |
+--------+-------+--------------+
| Ford   | Blue  |            1 |
| Ford   | White |            1 |
| Toyota | Black |            1 |
| Toyota | Green |            2 |
| Toyota | Red   |            1 |
| Nissan | Black |            1 |
| Smart  | White |            1 |
| BMW    | Blue  |            1 |
| BMW    | White |            1 |
+--------+-------+--------------+
9 rows in set (0.00 sec)

Allora, perché non sono i risultati che ci si aspettava? È perché, sebbene abbiamo selezionato il join esterno dalle auto ai marchi, non è stato specificato nel join ai colori, quindi quel particolare join riporterà solo risultati che corrispondono in entrambe le tabelle.

Ecco la query che funzionerebbe per ottenere i risultati che ci aspettavamo:

select
    a.brand,
    c.color,
    count(b.id) as countOfBrand
from
    brands a
        left outer join cars b
            on a.ID=b.brand
        left outer join colors c
            on b.color=c.ID
group by
    a.brand,
    c.color

+--------+-------+--------------+
| brand  | color | countOfBrand |
+--------+-------+--------------+
| BMW    | Blue  |            1 |
| BMW    | White |            1 |
| Ford   | Blue  |            1 |
| Ford   | White |            1 |
| Holden | NULL  |            0 |
| Nissan | Black |            1 |
| Smart  | White |            1 |
| Toyota | NULL  |            1 |
| Toyota | Black |            1 |
| Toyota | Green |            2 |
| Toyota | Red   |            1 |
+--------+-------+--------------+
11 rows in set (0.00 sec)

Come possiamo vedere, abbiamo due outer join nella query e i risultati stanno arrivando come previsto.

Ora, che ne dici di quegli altri tipi di join che chiedi? E gli incroci?

Ebbene, non tutti i database supportano l'intersection ma praticamente tutti i database ti permetteranno di creare un'intersezione attraverso un join (o almeno un'istruzione where ben strutturata).

Un'intersezione è un tipo di unione in qualche modo simile a una union come descritto sopra, ma la differenza è che solo restituisce righe di dati identiche (e intendo identiche) tra le varie singole query unite dall'unione. Verranno restituite solo le righe identiche sotto ogni aspetto.

Un semplice esempio potrebbe essere tale:

select
    *
from
    colors
where
    ID>2
intersect
select
    *
from
    colors
where
    id<4

Mentre una normale union query restituirebbe tutte le righe della tabella (la prima query restituiva qualsiasi cosa su ID>2 e il secondo qualsiasi cosa con ID<4 ) che risulterebbe in un set completo, una query di intersezione restituirebbe solo la riga corrispondente a id=3 poiché soddisfa entrambi i criteri.

Ora, se il tuo database non supporta un intersection query, quanto sopra può essere facilmente completato con la seguente query:

select
    a.ID,
    a.color,
    a.paint
from
    colors a
        join colors b
            on a.ID=b.ID
where
    a.ID>2
    and b.ID<4

+----+-------+----------+
| ID | color | paint    |
+----+-------+----------+
|  3 | Blue  | Metallic |
+----+-------+----------+
1 row in set (0.00 sec)

Se desideri eseguire un'intersezione tra due tabelle diverse utilizzando un database che non supporta intrinsecamente una query di intersezione, dovrai creare un join su ogni colonna delle tabelle.