SELECT: struttura di una query semplice

L'istruzione SELECT nel linguaggio SQL è quella forse più utilizzata in quanto ci permette di recuperare le informazioni di interesse dal database. La sua sintassi è semplice e ben strutturata ma bisogna conoscere alcuni vincoli che si nascondo dietro ogni clausola dell'istruzione. Mediante alcuni esempi scopriremo come scrivere query semplici ma allo stesso tempo utili in un contesto reale.

Share

Reading time: 5 minutes

Negli articoli precedenti abbiamo visto come creare le tabelle di un database (SQL: creazione di un database) e come inserire, aggiornare e cancellare i dati oltre al concetto delle transazioni (SQL: transazioni e manipolazione dei dati).  Ovviamente l’utilità di un database relazionale non è solamente di immagazzinare le informazioni in modo corretto e strutturato, ma di recuperare ciò che ci interessa efficientemente. In questo articolo analizzeremo la struttura delle interrogazioni, ossia dell’istruzione SELECT. Ci focalizzeremo sulle clausole principali e semplici per iniziare a comprendere come l’istruzione funziona. Se siete pronti possiamo partire!

Struttura di una query

Le query SQL hanno una struttura bene definita:

				
					SELECT [DISTINCT] ElencoAttributiDaVisualizzare
FROM ElencoTabelleDaUtilizzare
[WHERE CondizioniDiTupla ]
[GROUP BY ElencoAttributiDiRaggruppamento ]
[HAVING CondizioniSuAggregati ]
[ORDER BY ElencoAttributiDiOrdinamento ]

				
			

dove le parentesi quadre indicano che il termine all’interno è opzionale.

Di seguito useremo il seguente schema per illustrare le varie clausole dell’istruzione SELECT, dove le chiavi primarie sono sottolineate, i campi con asterisco indicano che possono assumere valori nulli, mentre le chiavi esterne hanno lo stesso nome delle chiavi primarie a cui si riferiscono.

FILM (CodF, Titolo, Data_uscita, Genere, DurataMinuti)

CINEMA (CodC, Nome, Indirizzo, Città, SitoWeb*)

SALA (CodC, NumeroSala, Capienza)

PROIEZIONE (CodC, NumeroSala, Data, OraInizio, OraFine, CodF)

Clausola SELECT

Nella clausola FROM si inseriscono le tabelle coinvolte nell’interrogazione, mentre nella clausola SELECT si inseriscono le informazioni che vogliono essere visualizzati nel risultato finale. In particolare, nella SELECT si possono inserire le colonne di interesse oppure il wildcard * per indicare che tutte le colonne a disposizione devono essere visualizzate. Ad esempio, la query

				
					SELECT * 
FROM FILM;

				
			

selezionerà tutti i record presenti nella tabella FILM e visualizzerà tutte le colonne a disposizione nell’ordine definito all’atto di creazione della tabella. Diversamente, se vogliamo visualizzare solo il titolo e il genere la query dovrà essere riscritta come segue:

				
					SELECT Titolo, Genere
FROM FILM;

				
			

Nel caso però esistano due o più film con lo stesso titolo e appartenenti allo stesso genere (come i remake) il risultato conterrà record duplicati. Per eliminare queste duplicazioni nel risultato è necessario usare la keyword DISTINCT nella clausola SELECT.

				
					SELECT DISTINCT Titolo, Genere
FROM FILM;

				
			

I campi possono essere rinominati aggiungendo un alias vicino al campo desiderato. E’ possibile usare la keyword AS per indicare esplicitamente l’assegnazione dell’alias. Ad esempio, se volessimo rinominare nel risultato la colonna genere come Categoria arà sufficiente scrivere la seguente query:

				
					SELECT Titolo, Genere AS Categoria
FROM FILM;


				
			

Clausola WHERE

La clausola WHERE permette di esprimere condizioni di selezione espresse singolarmente ad ogni record. Le condizioni sono rappresentate da un’espressione booleana di predicati semplici come espressioni di confronto tra attributi e costanti, ricerca testuale e valutazione dei valori NULL.

Ad esempio, se volessimo visualizzare i film di genere Avventura e con una durata superiore ai 90 minuti la query risulterebbe la seguente:

				
					SELECT *
FROM FILM
WHERE Genere=”Avventura” AND DurataMinuti > 90;


				
			

Diversamente se ci interessassero i fil di genere Avventura e Fantasy dovremmo usare l’operatore OR in quanto il singolo campo per ciascun record può solo assumere un valore alla volta. La query sarebbe così:

				
					SELECT *
FROM FILM
WHERE Genere=”Avventura” OR Genere=”Fantasy”;



				
			

Per la ricerca testuale è necessario usare l’operatore LIKE. Attenzione che non è una ricerca testuale come si intende comunemente, ma solo una ricerca di porzioni di stringhe. Supponiamo che vogliamo trovare tutti i film il cui titolo inizia con “Star”. Per far ciò useremo il simbolo % subito dopo la stringa Star in modo tale che dopo possano comparire un numero arbitrario di caratteri.

				
					SELECT *
FROM FILM
WHERE Titolo LIKE ”Star%”;




				
			

Diversamente se volessimo indicare che ci sia un solo carattere dopo Star è necessario usare il simbolo “_” come di seguito.

				
					SELECT *
FROM FILM
WHERE Titolo LIKE ”Star_”;





				
			

Infine, in alcuni casi è richiesto di verificare se un campo assume valore NULL o no. Dallo schema possiamo notare che il sito web dei cinema non è sempre disponibile. Pertanto, se volessimo visualizzare tutti i cinema che non hanno un sito web dobbiamo usare l’operatore IS la cui sintassi è la seguente:

				
					NomeAttributo IS [NOT] NULL





				
			

La query sarà quindi la seguente:

				
					SELECT * 
FROM CINEMA
WHERE SitoWeb IS NULL;
				
			

Diversamente se volessimo trovare tutti i cinema che hanno un sito web sarebbe sufficiente negare il predicato precedente.

				
					SELECT * 
FROM CINEMA
WHERE SitoWeb IS NOT NULL;
				
			

Clausola ORDER BY

Quando visualizziamo i risultati delle query precedentemente introdotte, l’ordinamento dei record ci sembra casuale. In effetti non è veramente casuale ma dipende dall’ordine in cui il database sta leggendo i dati su disco. Ciò però non ci aiuta in alcuni casi. Ad esempio, se volessimo visualizzare le sale con una capienza maggiore di 100 posti sarebbe anche utile ordinarle da quella più grande a quella più piccola. Per far ciò dobbiamo usare la clausola ORDER BY che ha la seguente sintassi:

				
					ORDER BY NomeAttributo [ASC | DESC]  {, NomeAttributo [ASC | DESC] }
				
			

dove le parentesi graffe indicano che il termine racchiuso può non comparire o essere ripetuto un numero arbitrario di volte, mentre il simbolo “|” indica che deve essere scelto uno tra i termini. L’ordinamento di default per molti DBMS è crescente (ASC) e quindi si può omettere.

Tornando al nostro esempio ci sarà sufficiente inserire un ordinamento discendente in base al campo Capienza. La query risulterà così:

				
					SELECT * 
FROM SALA
WHERE Capienza > 100
ORDER BY Capienza DESC;
				
			

Potremmo però trovare alcune sale che hanno la stessa capienza. In quei casi l’ordinamento sarà “casuale”. Se volessimo inserire un altro vincolo di ordinamento in caso di parità di capienza potremmo usare il numero di sala ottenendo la query seguente

				
					SELECT * 
FROM SALA
WHERE Capienza > 100
ORDER BY Capienza DESC, Numero;

				
			

Funzioni di aggregazione

 

Le funzioni di aggregazione operano su un insieme di valori e producono come risultato un unico valore (aggregato). Queste funzioni vengono valutate solo dopo l’applicazione di tutti i predicati nella clausola WHERE. Si possono usare nella clausola di SELECT e nella clausola HAVING.  Attenzione che, nel caso non sia definita la clausola di GROUP BY, non possono essere aggiunti nella SELECT altri attributi non aggregati.

Le funzioni di aggregazioni standard sono le seguenti.

COUNT

Conta il numero di elementi di un insieme, ossia le righe oppure i valori (eventualmente distinti) di uno o più attributi. La sua sintassi è:

				
					COUNT (<*| [DISTINCT | ALL] ListaAttributi >)}

				
			

Con il simbolo * si indica che il conteggio è riferito alle righe dell’insieme. Diversamente se si inserisce solo l’elenco degli attributi il conteggio viene fatto per i valori degli attributi che non assumono valore NULL. Infine, con la keyword DISTINCT il conteggio restituisce il numero di valori diversi per gli attributi specificati.

SUM

Calcola la somma dei valori degli attributi indicati e ammette come argomento anche un’espressione. Gli attributi devono essere di tipo numerico o temporali.

MIN e MAX

Calcolano i valori minimi e massimi e ammettono come argomento anche un’espressione. Gli attributi devono poter essere ordinabili, pertanto anche sui campi di tipo testuale possono essere applicati. Attenzione che l’ordinamento su stringhe dipende dalla codifica dei caratteri e quindi è influenzato dalle minuscole e maiuscole.

AVG

Calcola la media aritmetica di un attributo o di un’espressione. Gli attributi devono essere di tipo numerico o temporali.

Supponiamo di voler calcolare il numero di sale, il numero di cinema diversi in cui le sale sono presenti e alcune statistiche relative alla capienza delle sale. La query risulterà la seguente:

				
					SELECT COUNT(*) AS NumeroSale, COUNT(DISTINCT CodC) AS NumeroCinema, 
MIN(Capienza), MAX(Capienza), AVG(Capienza)
FROM SALA;

				
			

More To Explore

Database

SQL: correlazione

Nel linguaggio SQL è possibile condizionare l’esecuzione di una query in base ai valori delle tuple che si stanno analizzando. Questo comportamento si definisce mediante la correlazione, ossia condizioni nella clausola WHERE di una query nidificata che si riferiscono ad attributi delle tabelle della query esterna. Mediante alcuni esempi scopriremo quali operatori usano questo costrutto, come definire opportunamente le correlazioni e la sue alternative.

Database

SQL: CTE

Esprimere in linguaggio SQL query complesse può risultare veramente difficile. Dividere il problema in mini interrogazioni è la strategia migliore per ottenere velocemente i risultati sperati senza incorrere in errori. Le Common Table Expression, chiamate anche CTE, permettono di definire una sola volta le query di nostro interesse da riutilizzare più volte quando è necessario. La loro sintassi pulita aumenta la leggibilità degli script SQL, permette di debuggare il codice scritto e di creare logiche molto complesse per filtrare ed estrarre i dati. Mediante alcuni esempi scopriremo le loro potenzialità.

4 risposte

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!