giovedì 25 marzo 2021

SQL giocando con MySQL 8 e NetBeans 12 - Post 4 - SELECT WHERE

Ora che si è visto come limitare il numero di record prodotti da una query, anche al fine di una paginazione nella visualizzazione dei dati, sarebbe però più comodo limitare ulteriormente i dati prodotti attraverso dei criteri di ricerca senza dover cercarli pagina per pagina. A tale scopo viene in aiuto la clausola WHERE del comando SELECT.Con la WHERE è possibile fornire una condizione che il record estratto deve soddisfare per entrare a far parte della tabella risultante dalla interrogazione della base dati. Partiamo subito con un esempio:

SELECT * FROM city WHERE ID=1000;

Come si può vedere con una semplice query abbiamo estratto il solo record con ID 1000. ID è un campo numerico di tipo intero, infatti le colonne di una tabella hanno un tipo associato che in questo caso è Integer. Se si è curiosi di vedere subito gli altri tipi c'è la documentazione ufficiale di MySQL. Il record restituito è solo uno perchè ID è la chiave primaria, quindi è unica all'interno della tabella individuando esattamente una riga. Il fatto che il record atteso sia uno rende inutile la specificazione della clausola LIMIT.

Oltre all'operatore di uguaglianza ci sono i seguenti operatori di confronto comuni:
= uguaglianza; != disuguaglianza; < minoranza; > maggioranza; <= minore o uguale; >= maggiore o uguale.
Ci sono poi alcuni costrutti del linguaggio quali:
nomeCampo BETWEEN valore AND altroValore 
ritorna true se il valore del campo è compreso tra i due valori estremi inclusi. Similmente si ha la negazione 
nomeCampo NOT BETWEEN valore AND altroValore 

nomeCampo LIKE pattern 
che verifica se l'espressione prima del like riscontra il pattern fornito. Un uso comune è con i caratteri speciali % e _ che all'interno della stringa di pattern equivalgono a zero o più caratteri (%) ed esattamente un carattere (_). Per non utilizzare i due caratteri precedenti come caratteri jolly, occorre farli precedere da un back slash. Similmente si ha la negazione 
nomeCampo NOT LIKE pattern

Per una lista completa degli operatori e funzioni di confronto si può consultare il manuale di MySQL.
Vediamo quindi qualche esempio con questi operatori:
SELECT * FROM city WHERE district LIKE "%java%" LIMIT 0,10;
SELECT * FROM city WHERE district LIKE "%java%" LIMIT 10,10;
SELECT * FROM city WHERE district LIKE "%java%" LIMIT 20,10;
SELECT * FROM city WHERE district LIKE "%java%" LIMIT 30,10;
SELECT * FROM city WHERE district LIKE "%java%" LIMIT 40,10;

Questa query dice di selezionare tutti campi dalla tabella city dove il campo district è simile a "%java% limitatamente a gruppi di 10 righe saltate un certo numero di righe. Più semplicemente sono estratti tutte quelle righe in cui nel campo district sia presente la parola java indipendentemente da quanti caratteri la precedano o la seguano creando 4 schede da 10 record l'una. 
Se avessimo voluto la selezione opposta ossia tutti i record che non contengono la parola java nel campo district, avremmo utilizzato NOT LIKE. 

SELECT * FROM city WHERE population > 100000 ORDER BY population DESC;

Con questa query sono estratte tuttle le città con popolazione superiore ai 100mila abitanti ed ordinate dalla più popolosa alla meno.

SELECT * FROM city WHERE id BETWEEN 101 AND 150 ORDER BY countrycode ASC, name DESC LIMIT 20,10;

In questo casto sono estratti 50 record, ossia quelli con ID che vanno da 101 a 150, in ordine crescente per countryCode e a parità di countryCode in ordine decrescente sul nome in gruppi di 10 limitatamente alla 3° pagina. Ricordiamo che con OFFSET 20, avendo gruppi di 10 la pagina è la terza, la seconda ha OFFSET 10 e la prima OFFSET 0.
La clausola WHERE non accetta una condizione formata da un solo confronto, ma anche una combinazione di confronti uniti da AND o OR. In più abbiamo anche NOT e IN.

SELECT district, name, population FROM city WHERE countrycode="ITA" AND population>200000 ORDER BY district, name;

Con questa query sono estratte tra le città con countrycode ITA, quelle con popolazione superiore a 200k abitanti ordinate per regione e quindi per nome. Si osservi anche che l'elenco dei campi subito dopo il comando SELECT non solo stabilisce quali campi estrarre ma anche l'ordine in cui presentarli.
Per variare l'ordine di valutazione degli operatori logici è possibile utilizzare le parentesi tondo.

Un ultimo esempio:
SELECT countrycode, district, name, population FROM city WHERE countrycode IN ("ITA","USA") and population>200000 ORDER BY countrycode, district, population DESC;

Questa query estrae i campi specificate, cercando quelli in cui countrycode appartiene alla lista di valori ("ITA","USA") e le città hanno più di 200k abitanti. Quindi le ordina in base a coutrycode, district in ordine crescente e per ogni district in ordine decrescente per popolazione. Si osservi che l'ordinamento di default è crescente. Anche nel caso del costrutto IN, possiamo ottenere l'insieme opposto di risultati con NOT IN.