Brook Preloader

QL, selezione e proiezione

L’acronimo QL (Query Language) identifica il sottogruppo del linguaggio SQL dedicato all’estrazione di nuove informazioni partendo da dati già posseduti.

Dato che le informazioni che intendiamo estrarre sono in forma tabellare, queste possono essere filtrate sia nel contenuto (per riga corrispondente ai filtri di ricerca) che per dato di pertinenza (le colonne che le compongono).

Dichiariamo una tabella con i seguenti campi: Nome, Cognome, Sesso e Codice Fiscale stando attenti a non permettere l’inserimento di due codici fiscali uguali:

 

 -- DDL
 CREATE TABLE Persona (
     personaID INTEGER PRIMARY KEY AUTO_INCREMENT
     nome VARCHAR(250) NOT NULL,
     cognome VARCHAR(250) NOT NULL,
     sesso VARCHAR(1),
     cod_fis VARCHAR(16) NOT NULL UNIQUE,
     eta INTEGER NOT NULL
 );

Popoliamo la tabella con dei record di esempio:

 

 INSERT INTO Persona ('nome', 'cognome', 'sesso', 'cod_fis') VALUES
 ('Giovanni', 'Pace', 'M', 'PCAGNN', 35),
 ('Ester', 'Frittella', 'F', 'ESTFRT', 24),
 ('Claudio', 'Romero', NULL, 'CLDRMR', 33),
 ('Valeria', 'Verdi', 'F', 'VLRVRD', 15),
 ('Giovanni', 'Giorgio', 'M', 'GNNGRG', 87);

Avremo una rappresentazione grafica della tabella equiparabile a questa:

 

-------------------------------------------------------------------
| personaID |      nome |    cognome |     sesso |  cod_fis | eta |
-------------------------------------------------------------------
|         1 |  Giovanni |       Pace |         M |   PCAGNN |  35 |
|         2 |     Ester |  Frittella |         F |   ESTFRT |  24 |
|         3 |   Claudio |     Romero |      NULL |   CLDRMR |  33 |
|         4 |   Valeria |      Verdi |         F |   VLRVRD |  15 |
|         5 |  Giovanni |    Giorgio |         M |   GNNGRG |  87 |
-------------------------------------------------------------------

Definiamo le due tipologie di filtro applicate sulla tabella come:

 

  • Filtro orizzontale: SELEZIONE
  • Filtro verticale: PROIEZIONE

 

 

La selezione (il filtro orizzontale)

Il comando principale del QL è esprimibile come una combinazione di tre keyword principali, SELECT, FROM e WHERE.

Il concetto è esprimibile in una struttura che di questo tipo:

SELECT <elenco_colonne> FROM <nome_tabella> WHERE <filtro_applicabile>;

La terza keyword WHERE è opzionale e corrisponde all’interrogazione tabellare senza filtri, operazione molto pericolosa per data set molto numerosi dato che potrebbe richiedere troppa memoria rispetto a quella disponibile.

Analizziamo la seguente query:

 

/*
 Seleziona tutte le righe dalla tabella Persona
 */
 ​
 SELECT * 
     FROM Persona;
 ​
 /*
 Seleziona le righe dalla tabella Persona costruendo una tabella con le colonne personaID, nome, cognome, sesso, cod_fi, eta 
 */
 ​
 SELECT personaID, nome, cognome, sesso, cod_fis, eta 
     FROM Persona;

Di certo è la query più semplice che corrisponde all’interrogazione della tabella Persona selezionando tutte le colonne senza porre filtri sui dati.

La differenza tra la prima riga dove viene introdotto l’operatore * che corrisponde a tutte le colonne nell’ordine della loro dichiarazione e ciò che è stato dichiarato nella seconda riga è esplicito, ecco il risultato:

 

-------------------------------------------------------------------
| personaID |      nome |    cognome |     sesso |  cod_fis | eta |
-------------------------------------------------------------------
|         1 |  Giovanni |       Pace |         M |   PCAGNN |  35 |
|         2 |     Ester |  Frittella |         F |   ESTFRT |  24 |
|         3 |   Claudio |     Romero |      NULL |   CLDRMR |  33 |
|         4 |   Valeria |      Verdi |         F |   VLRVRD |  15 |
|         5 |  Giovanni |    Giorgio |         M |   GNNGRG |  87 |
-------------------------------------------------------------------

 

La clausula WHERE

Il filtro sui record rispetto ad un singolo dato viene introdotto dalla clausula WHERE <nome_riga> <operatore> <valore>.

Ecco un esempio pratico:

 

/*
 Seleziona tutte le righe dalla tabella Persona dove la colonna nome contiene dati uguali a 'Giovanni'
 */
 ​
 SELECT * 
     FROM Persona 
     WHERE nome = 'Giovanni';

Il risultato dell’operazione avrà come risultato una nuova tabella composta esattamente in questo modo:

 

-------------------------------------------------------------------
| personaID |      nome |    cognome |     sesso |  cod_fis | eta |
-------------------------------------------------------------------
|         1 |  Giovanni |       Pace |         M |   PCAGNN |  35 |
|         5 |  Giovanni |    Giorgio |         M |   GNNGRG |  87 |
-------------------------------------------------------------------

Tutte le righe che non soddisfano la clausula introdotta all’interno del filtro orizzontale WHERE non vengono incluse nella tabella risultate.

L’operazione più semplice è di certo la comparazione per uguaglianza ( = ), la sua controparte differenza ( <> ) può essere utilizzata in questo modo:

 

 /*
 Seleziona tutte le righe dalla tabella Persona dove la colonna nome contiene dati diversi da 'Giovanni'
 */
 ​
 SELECT * 
     FROM Persona 
     WHERE nome <> 'Giovanni';

Il risultato sarà:

 

-------------------------------------------------------------------
| personaID |      nome |    cognome |     sesso |  cod_fis | eta |
-------------------------------------------------------------------
|         2 |     Ester |  Frittella |         F |   ESTFRT |  24 |
|         3 |   Claudio |     Romero |      NULL |   CLDRMR |  33 |
|         4 |   Valeria |      Verdi |         F |   VLRVRD |  15 |
-------------------------------------------------------------------

 

Where composta

Il filtro orizzontale può essere composto in modo tale da diventare sempre più specifico introducendo la logica booleana:

 

/*
 Seleziona tutte le righe dalla tabella Persona dove la colonna nome contiene dati uguali a 'Giovanni' E la colonna cognome contiene dati uguali a 'Pace'
 */
 ​
 SELECT * 
     FROM Persona 
     WHERE nome = 'Giovanni' AND cognome = 'Pace';

Ecco il risultato:

 

-------------------------------------------------------------------
| personaID |      nome |    cognome |     sesso |  cod_fis | eta |
-------------------------------------------------------------------
|         1 |  Giovanni |       Pace |         M |   PCAGNN |  35 |
-------------------------------------------------------------------

Come possiamo osservare l’operatore AND, che nella frase in italiano che traduce la query è corrispondente ad E, aumenta la specificità del filtro sui dati, infatti viene introdotta per restringere sempre di più i record da rappresentare.

Come obiettivo opposto invece l’operatore OR è inclusivo di filtri di diverso genere, vediamo la sua espressione:

 

 /*
 Seleziona tutte le righe dalla tabella Persona dove la colonna nome contiene dati uguali a 'Giovanni' O 'Ester'
 */
 ​
 SELECT * 
     FROM Persona 
     WHERE nome = 'Giovanni' OR nome = 'Ester';

Il risultato sarà:

 

-------------------------------------------------------------------
| personaID |      nome |    cognome |     sesso |  cod_fis | eta |
-------------------------------------------------------------------
|         1 |  Giovanni |       Pace |         M |   PCAGNN |  35 |
|         2 |     Ester |  Frittella |         F |   ESTFRT |  24 |
|         5 |  Giovanni |    Giorgio |         M |   GNNGRG |  87 |
-------------------------------------------------------------------