SELECT: operatori insiemistici

Talvolta si ha la necessità si operare sui risultati di diverse query come se fossero degli insiemi. Non dobbiamo usare un linguaggio di programmazione per fare queste operazioni sui dati, ma possiamo usare dei costrutti del linguaggio SQL. Gli operatori a disposizione ci permettono sia di unire che escludere i risultati due insiemi, oltre a definire l'intersezione. Con alcuni esempi capiremo come usare questi costrutti in modo appropriato.

Share

Reading time: 4 minutes

Grazie alle conoscenze acquisite negli articoli precedenti, SELECT: struttura di una query semplice, SELECT: query con JOIN e GROUP BY, SELECT: operatore IN e SELECT: operatore NOT IN e costruttore di tupla, siamo in grado di scrivere query abbastanza complesse. Infatti, possiamo definire gruppi, calcolare statistiche, includere e/o escludere records in base al risultato di altre query. Abbiamo veramente un bel po’ di strumenti! Il linguaggio SQL, però, ci mette a disposizione ancora altre funzionalità e costrutti per aumentare la nostra produttività e le possibilità di estrarre dati di interesse con vincoli molto particolari. In questo articolo affronteremo l’utilizzo degli operatori insiemistici che ci permettono di unire i risultati di due query con la teoria degli insiemi.

Come negli articoli precedenti, useremo lo schema, ormai noto, relativo alle proiezioni dei film nei cinema. Lo riportiamo qui sotto per chi non avesse letto gli altri articoli.

FILM (CodF, Titolo, Data_uscita, Genere, DurataMinuti)
CINEMA (CodC, Nome, Indirizzo, Città, SitoWeb*)
SALA (CodC, NumeroSala, Capienza)
PROIEZIONE (CodC, NumeroSala, Data, OraInizio, OraFine, CodF)

Vi ricordo che la notazione usata per descrivere lo schema usa la sottolineatura per indicare i campi che compongono la chiave primaria e l’asterisco per segnalare la possibilità di assegnare valori NULL al campo. Infine, per semplificare, le chiavi esterne hanno lo stesso nome delle chiavi primarie a cui si riferiscono. Procediamo quindi a vedere i vari operatori.

Operatori insiemistici

Gli operatori insiemistici sono i seguenti:

  • UNION
  • INTERSECT
  • EXCEPT

Essi hanno la funzione di mettere insieme i risultati che derivano da due query. Hanno però una particolarità: richiedono che gli schemi dei risultati siano compatibili tra di loro. Perciò, a differenza degli operatori IN e NOT IN che mettevano “in comunicazione” due query, questi operano in modo analogo se e solo se gli attributi selezionati sono gli stessi. Analizziamo più nel dettaglio ciascun operatore per capire le loro peculiarità.

UNION

Questo operatore esegue l’unione delle due espressioni relazionali A e B, ossia dei risultati di due istruzioni di SELECT. La sintassi è la seguente:

				
					A UNION [ALL] B
				
			

dove il parametro ALL è opzionale. Nel caso venga omesso i duplicati delle righe selezionate vengono rimosse. Diversamente tutti i risultati vengono restituiti all’utente. Capiamo meglio mediante un esempio come funziona.

Supponiamo di voler trovare i nomi dei cinema di Torino o che hanno almeno una sala con una capienza maggiore di 200. Dividiamo anche in questo caso il problema in due sottoproblemi. Il primo sarà relativo a trovare tutti i cinema di Torino e si risolve con una query molto semplice.

				
					SELECT Nome
FROM CINEMA
WHERE Città=’Torino’;
				
			

Il secondo problema, invece, riguarda l’individuazione dei cinema con almeno una sala con capienza maggiore di 200. Dobbiamo per prima cosa filtrare le righe della tabella SALA in base al valore dell’attributo capienza. Dopodichè, visto che ci serve il nome del cinema sarà sufficiente effettuare un join con la tabella CINEMA. La query finale sarà la seguente:

				
					SELECT Nome
FROM CINEMA C, SALA S
WHERE C.CodC=S.CodC
AND Capienza > 200;
				
			

Ora non ci resta che mettere insieme i due risultati. Dal momento che abbiamo selezionato in entrambe le query il solo attributo Nome, gli schemi sono per definizione compatibili. Possiamo, quindi, applicare l’operatore UNION così da ottenere il risultato desiderato. Ovviamente se ci fosse un cinema che è situato in Torino e ha una sala con una capienza maggiore di 200 comparirà in entrambi i risultati delle due query appena scritte. Per evitare che venga ripetuto è sufficiente omettere il parametro ALL. La query finale sarà:

				
					SELECT Nome
FROM CINEMA
WHERE Città=’Torino’

UNION

SELECT Nome
FROM CINEMA C, SALA S
WHERE C.CodC=S.CodC
AND Capienza > 200

				
			

INTERSECT

Come dice il nome, questo operatore esegue un’intersezione dei risultati di due istruzioni SELECT. Date, pertanto, due query A e B, la sua sintassi è

				
					A INTERSECT B

				
			

Proviamo ad applicarlo ad un esempio concreto. Supponiamo di voler individuare le date in cui sono usciti i film e sono stati anche proiettati alcuni film nei cinema che abbiamo a database. Pertanto, scriviamo due query che selezionano le date di uscita dei film e quelle di proiezione. L’intersezione tra questi due insieme saranno quelle che vogliamo trovare. La prima query ritornerà le date di uscita dalla tabella FILM, mentre la seconda quelle di proiezione. Per ottenere il risultato finale useremo l’operatore INTERSECT.

				
					SELECT Data_uscita
FROM FILM

INTERSECT 

SELECT Data
FROM PROIEZIONE;
				
			

Come potete notare i nomi dei campi sono diversi. Questo, in molti database, non incide sulla compatibilità degli schemi in quanto gli attributi selezionati sono dello stesso tipo (ossia DATE). Ovviamente, alcuni database potrebbero richiedere che il nome sia lo stesso e in quel caso sarà sufficiente rinominare mediante l’operatore AS i campi selezionati.

L’operazione di intersezione può essere sostituita mediante il join o l’operatore IN. Nel caso del join è sufficiente inserire nella clausola FROM le tabelle interessate dall’intersezione, mentre nella clausola WHERE le condizioni di join tra gli attributi presenti nelle clausole SELECT delle due query. Usando queste regole la query precedente risulterebbe:

				
					SELECT F.Data_uscita
FROM FILM F, PROIEZIONE P
WHERE F.Data_uscita=P.Data;
				
			

La condizione di join, quindi, non è quella “classica” sulle chiavi primarie/esterne che non essere ovviamente inserita per non inficiare il risultato desiderato.

Se vogliamo usare invece l’operatore IN, dovremo usare una delle due query come un’interrogazione nidificata, mentre gli attributi nella clausola SELECT esterna, uniti da un costruttore di tupla, costituiscono la parte sinistra dell’operatore IN. In pratica, la query di prima possiamo scriverla così:

				
					SELECT Data_uscita
FROM FILM
WHERE Data_uscita IN (SELECT Data
                      FROM PROIEZIONE);

				
			

EXCEPT

Infine, l’operatore EXCEPT effettua una differenza tra i risultati di due query. Oltre alla compatibilità degli schemi, questo operatore non gode della proprietà commutativa. Ciò significa che l’ordine di scrittura, e di conseguenza di esecuzione, delle query è rilevante. Date due query A e B, la sintassi è:

				
					A EXCEPT B
				
			

Riprendiamo l’esempio sulle date. Supponiamo di voler trovare le date di uscita dei film in cui non sono stati proiettati film. Le query sono quelle viste in precedenza ma dovremo usare l’operatore EXCEPT.

				
					SELECT Data_uscita
FROM FILM

EXCEPT

SELECT Data
FROM PROIEZIONE;
				
			

Essendo una differenza, il concetto su cui opera è lo stesso dell’esclusione dell’operatore NOT IN che può essere usato in sua vece. Per poterlo usare la seconda query diventerà nidificata all’interno dell’operatore NOT IN, mentre gli attributi nella clausola SELECT della prima query, uniti da un costruttore di tupla, costituiranno la parte sinistra dell’operatore NOT IN. Il risultato finale è il seguente:

				
					SELECT Data_uscita
FROM FILM
WHERE Data_uscita NOT IN (SELECT Data
                          FROM PROIEZIONE);

				
			

More To Explore

Intelligenza artificiale

Gradio: applicazioni web in python per AI [parte1]

Scrivere applicazioni web per i nostri modelli di machine learning e/o di intelligenza artificiale può richiedere molto tempo e competenze che non sono in nostro possesso. Per snellire e velocizzare questo compito ci viene in aiuto Gradio, una libreria Python pensata per creare applicazioni web con poche righe di codice. Scopriamo le sue funzionalità base con alcuni esempi.

Intelligenza artificiale

AI: le migliori tecniche di prompt per sfruttare i LLM

Le tecniche di prompt sono alla base dell’uso dei LLM. Esistono diversi studi e linee guide per ottenere i migliori risultati da questi modelli. Analizziamo alcuni di essi per estrarre i principi fondamentali che ci permetteranno di ottenere le risposte desiderate in base al nostro compito.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Design with MongoDB

Design with MongoDB!!!

Buy the new book that will help you to use MongoDB correctly for your applications. Available now on Amazon!