Torna all'elenco degli articoli Articoli
Tempo di lettura: 8 minuti

Guida illustrata alle Join non uguali in SQL

Sapevate che in SQL un join non deve necessariamente basarsi su corrispondenze identiche? In questo post analizziamo la join SQL non equi, che utilizza operatori "non uguali" per abbinare i record.

Abbiamo già parlato di diversi tipi di join, tra cui self join e CROSS JOIN, INNER JOIN e OUTER JOIN. Questi tipi di join si presentano in genere con il segno di uguale (=). Tuttavia, alcune giunzioni utilizzano condizioni diverse dal segno di uguaglianza (=). Questo è un esempio di join non equi in SQL ed è quello di cui parleremo in questo articolo.

Che cos'è una giunzione non equivalente in SQL?

Se avete letto gli altri post di questa serie, sapete come usare le join in SQL per combinare i record in base alle corrispondenze di valori esatti. Ma cosa succede se si cerca un record che non ha bisogno di una corrispondenza esatta? Supponiamo di voler unire i record in base a un intervallo di valori. O forse si vogliono tutti i record che non corrispondono a qualche valore. In questi casi, è necessario utilizzare una join SQL non equi.

Come un self join, un join SQL non equi non ha una parola chiave specifica; non vedrete mai le parole NON EQUI JOIN nel codice SQL di nessuno. Sono invece definite dal tipo di operatore presente nella condizione di join: tutto ciò che non è un segno di uguale significa un join non equi. Come si vedrà nel riquadro seguente, a volte il segno di uguale fa parte dell'operatore. Ma in una join SQL non equi, non è mai l'intero operatore da solo. Di seguito sono riportati alcuni operatori di join non equi e il loro significato:

Operator Meaning
“>” Greater than
“>=” Greater than or equal to
“<” Less than
“<=” Less than or equal to
“!=” Not equal to
”<>” Not equal to (ANSI Standard)
BETWEEN … AND Values in a range between x and y

Infine, è bene sapere che un join SQL non equi può essere usato solo con una o due tabelle.

Conoscere i dati

Prima di iniziare a descrivere le join non equi, familiarizziamo con alcuni dei dati che utilizzeremo. Verranno anche esaminate le giunzioni equi.

Qui sotto abbiamo la tabella "person", che contiene i record delle persone coinvolte nell'acquisto di un appartamento (ad esempio un condominio). Tutte le colonne sono autoesplicative, ma si notino le colonne "min_price" e "max_price". Si tratta della fascia di prezzo della persona per l'acquisto di un appartamento. La colonna "apartment_id" collegherà questa tabella alla tabella "apartment".

id first_name last_name rooms min_price max_price apartment_id
1 Anne Miller 2 40,000 150,000 2
2 John Harris 1 20,000 50,000 2
3 Michael Moore 2 200,000 300,000 6
4 Oliver Watson 4 30,000 100,000 7

La tabella "apartment" contiene informazioni sugli appartamenti, sul numero di stanze e sulla città. Si noti che i valori della colonna "id" sono praticamente gli stessi della colonna "apartment_id".

id rooms price city
1 2 30,000 Houston
2 2 45,000 Dallas
3 3 125,000 Chicago
4 5 245,000 Los Angeles
5 4 340,000 San Jose
6 4 220,000 San Diego
7 1 36,000 Cleveland

Ora esaminiamo le giunzioni equi.

Che cos'è una giunzione equi SQL?

La maggior parte delle join SQL sono join equi. Una join equi è un'operazione di JOIN che utilizza un segno di uguale e solo un segno di uguale. È possibile vedere query che utilizzano più di una condizione di join; se una condizione è un segno di uguale e l'altra no, questa è considerata una join non equi in SQL.

Come abbiamo già detto, le join equi richiedono una corrispondenza esatta tra due colonne. Guardate la query qui sotto:

SELECT first_name, last_name, price, city 
FROM person 
JOIN  apartment  ON   apartment.id = person.apartment_id ;

Questa query seleziona il nome e il cognome del cliente, il prezzo dell'appartamento e la città in cui si trova l'appartamento. Abbiamo utilizzato un JOIN (noto anche come INNER JOIN) per combinare i dati delle colonne "person" e "apartment". Questo join mostra solo i record che possono essere confrontati in entrambe le tabelle. Nella condizione di unione, abbiamo usato l'operatore equals sulla colonna "apartment_id" della tabella "person" e la colonna "id" della tabella "apartment" per trovare una corrispondenza esatta.

La tabella risultante contiene le seguenti righe:

first_name last_name price city
Anne Miller 30,000 Houston
John Harris 45,000 Dallas
Michael Moore 220,000 San Diego
Oliver Watson 36,000 Cleveland

Abbiamo visto come funziona un join equi. Vediamo ora come funziona una join SQL non equi.

Utilizzo di un join SQL non equi con due tabelle

SELECT first_name, last_name, min_price, max_price, price, city 
FROM person JOIN apartment ON apartment.id != person.apartment_id
    AND price BETWEEN min_price AND max_price
ORDER BY last_name;

Abbiamo usato l'operatore JOIN per combinare i record delle tabelle "person" e "apartment". Abbiamo selezionato il nome e il cognome di ogni persona, il prezzo minimo e massimo desiderato e il prezzo e la città di tutti gli appartamenti non scelti dal cliente. Abbiamo utilizzato l'operatore BETWEEN... AND per abbinare i prezzi degli appartamenti. Abbiamo anche usato l'operatore "!=" in una condizione con "apartment_id" dalla tabella "person" e "id" dalla tabella "apartment". In questo modo, abbiamo rimosso l'appartamento scelto dalla tabella dei risultati.

La tabella dei risultati ha questo aspetto:

first_name last_name min_price max_price price city
John Harris 20,000 50,000 30,000 Houston
John Harris 20,000 50,000 36,000 Cleveland
Anne Miller 40,000 150,000 125,000 Chicago
Michael Moore 200,000 300,000 245,000 Los Angeles
Oliver Watson 30,000 100,000 45,000 Dallas
Oliver Watson 30,000 100,000 30,000 Houston

L'appartamento di Dallas scelto da John Harris non è stato mostrato. Si noti che avrebbe potuto scegliere un appartamento a Houston (30.000 dollari) o a Cleveland (36.000 dollari). Entrambi gli appartamenti rientrano nella fascia di prezzo di 20.000-50.000 dollari.

SQL Non Equi Join in Self Join

Vediamo ora come funziona una join SQL non equi quando una tabella è unita a se stessa. I nostri esempi si baseranno sulla tabella "playing_cards" mostrata di seguito. Essa contiene le seguenti colonne: "id" (un identificatore interno), "rank" (il rango o valore nominale della carta) e "suit" (il seme della carta).

id rank suit
1 A Hearts
2 A Spades
3 A Clubs
4 K Spades
5 K Diamonds
6 Q Clubs
7 J Spades

Queste sono le carte memorizzate nella tabella "playing_cards":

Si noti che abbiamo solo sette carte nel set.

Vediamo tre modi per utilizzare le join non equi in queste circostanze.

1. Trovare tutte le coppie di carte

In base all'insieme di carte presenti nella tabella "playing_cards", troveremo tutte le possibili coppie di carte.

Osserviamo la query:

SELECT c1.rank, c1.suit, c2.rank,c2.suit
FROM playing_cards c1 
JOIN playing_cards c2 ON c1.id != c2.id 
ORDER BY c1.rank;

Nella query precedente, abbiamo unito la tabella "playing_cards" a se stessa utilizzando gli alias c1 e c2. (Abbiamo quindi utilizzato l'operatore di disuguaglianza "!=", creando un join SQL non equi, per ottenere tutte le possibili coppie di carte. Questo operatore mostra le coppie di carte in ordine variabile e rimuove le coppie di carte identiche allo stesso tempo.

La tabella seguente mostra alcune delle righe risultanti. Abbiamo evidenziato le righe contenenti coppie duplicate.

rank suit rank suit
A Spades A Hearts
A Spades A Clubs
A Spades K Spades
A Spades K Diamonds
A Spades Q Clubs
A Spades J Spades
A Clubs A Hearts
A Clubs A Spades
A Clubs K Spades
A Clubs K Diamonds
A Clubs Q Clubs
A Clubs J Spades

Vediamo i primi 12 dei 42 record totali. L'immagine seguente mostra le coppie selezionate:

2. Eliminazione delle coppie di carte duplicate

Le coppie di carte restituite dall'ultima query non erano uniche perché il risultato della query includeva coppie mostrate in ordine inverso, cioè "Asso di picche con Asso di fiori" e "Asso di fiori con Asso di picche".

Nella prossima query verranno restituite solo coppie uniche. La posizione delle carte nella coppia non ha importanza.

SELECT c1.rank, c1.suit,c2.rank,c2.suit
FROM playing_cards c1 
JOIN playing_cards c2 ON c1.id < c2.id 
ORDER BY c1.rank;

Come si vede, abbiamo utilizzato un join SQL non equi con l'operatore "<" invece di "!=". Di conseguenza, abbiamo ottenuto coppie di carte uniche.

E questi sono i risultati:

rank suit rank suit
A Spades A Hearts
A Clubs A Hearts
A Clubs A Spades
J Spades A Hearts
J Spades A Spades
J Spades A Clubs
J Spades K Spades
J Spades K Diamonds
J Spades Q Clubs
K Spades A Hearts
K Spades A Spades
K Spades A Clubs
K Diamonds A Hearts
K Diamonds A Spades
K Diamonds A Clubs
K Diamonds K Spades
Q Clubs A Hearts
Q Clubs A Spades
Q Clubs A Clubs
Q Clubs K Spades
Q Clubs K Diamonds

In questo caso, 21 record soddisfano la condizione e tutte le coppie risultanti appaiono una sola volta.

3. Trovare coppie di carte con lo stesso seme

Nella prossima query, selezioneremo coppie uniche di carte con lo stesso seme (Cuori, Picche, Fiori e Quadri). Riuscite a trovare l'operatore non equi che abbiamo usato?

SELECT c1.rank, c1.suit,c2.rank,c2.suit
FROM playing_cards c1 
JOIN playing_cards c2 ON c1.rank < c2.rank AND c1.suit = c2.suit ;

La query precedente utilizza due condizioni: una che confronta il "rango" delle carte e un'altra che confronta la colonna "suit".

Osservate il risultato della query.

rank suit rank suit
A Spades K Spades
J Spades K Spades
A Clubs Q Clubs
A Spades J Spades

Solo quattro record corrispondono alle condizioni di JOIN. La situazione è illustrata di seguito.

Per saperne di più su SQL

Ora sapete cos'è e come funziona una join non equi in SQL. Se siete interessati a saperne di più su SQL, consultate i corsi di LearnSQL.it. Potete mettere in pratica le vostre nuove competenze con esercizi interattivi. Potete anche imparare di più sulle unioni SQL nei nostri post, SQL Joins e Learning SQL JOINs Using Real-Life Situations.