SQL: query secondarie

Una query subquery o interna o una query annidata è una query all'interno di un'altra query SQL e incorporata nella clausola WHERE.

Una sottoquery viene utilizzata per restituire i dati che verranno utilizzati nella query principale come condizione per limitare ulteriormente i dati da recuperare.

Le sottoquery possono essere utilizzate con le istruzioni SELECT, INSERT, UPDATE e DELETE insieme a operatori come =, <,>,> =, <=, IN, BETWEEN, ecc.

Ci sono alcune regole che le sottoquery devono seguire:

  • Le sottoquery devono essere racchiuse tra parentesi.

  • Una sottoquery può avere solo una colonna nella clausola SELECT, a meno che non siano presenti più colonne nella query principale per la sottoquery per confrontare le colonne selezionate.

  • Un comando ORDER BY non può essere utilizzato in una sottoquery, sebbene la query principale possa utilizzare un ORDER BY. Il comando GROUP BY può essere utilizzato per eseguire la stessa funzione di ORDER BY in una sottoquery.

  • Le sottoquery che restituiscono più di una riga possono essere utilizzate solo con più operatori di valore come l'operatore IN.

  • L'elenco SELECT non può includere riferimenti a valori che restituiscono un BLOB, ARRAY, CLOB o NCLOB.

  • Una sottoquery non può essere immediatamente racchiusa in una funzione set.

  • L'operatore BETWEEN non può essere utilizzato con una sottoquery. Tuttavia, l'operatore BETWEEN può essere utilizzato all'interno della sottoquery.

Sottoquery con l'istruzione SELECT

Le sottoquery vengono utilizzate più di frequente con l'istruzione SELECT. La sintassi di base è la seguente:

SELECT column_name [, column_name ]
FROM   table1 [, table2 ]
WHERE  column_name OPERATOR
   (SELECT column_name [, column_name ]
   FROM table1 [, table2 ]
   [WHERE])

Esempio

Considera la tabella CLIENTI con i seguenti record:

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

Ora, controlliamo la seguente sottoquery con un'istruzione SELECT.

SQL> SELECT * 
   FROM CUSTOMERS 
   WHERE ID IN (SELECT ID 
         FROM CUSTOMERS 
         WHERE SALARY > 4500) ;

Ciò produrrebbe il seguente risultato.

+----+----------+-----+---------+----------+
| ID | NAME     | AGE | ADDRESS | SALARY   |
+----+----------+-----+---------+----------+
|  4 | Chaitali |  25 | Mumbai  |  6500.00 |
|  5 | Hardik   |  27 | Bhopal  |  8500.00 |
|  7 | Muffy    |  24 | Indore  | 10000.00 |
+----+----------+-----+---------+----------+

Sottoquery con l'istruzione INSERT

Le sottoquery possono essere utilizzate anche con le istruzioni INSERT. L'istruzione INSERT utilizza i dati restituiti dalla sottoquery per inserirli in un'altra tabella. I dati selezionati nella sottoquery possono essere modificati con qualsiasi funzione di carattere, data o numero.

La sintassi di base è la seguente.

INSERT INTO table_name [ (column1 [, column2 ]) ]
   SELECT [ *|column1 [, column2 ]
   FROM table1 [, table2 ]
   [ WHERE VALUE OPERATOR ]

Esempio

Considera una tabella CUSTOMERS_BKP con struttura simile alla tabella CUSTOMERS. Ora per copiare la tabella CUSTOMERS completa nella tabella CUSTOMERS_BKP, puoi utilizzare la seguente sintassi.

SQL> INSERT INTO CUSTOMERS_BKP
   SELECT * FROM CUSTOMERS 
   WHERE ID IN (SELECT ID 
   FROM CUSTOMERS) ;

Sottoquery con l'istruzione UPDATE

La sottoquery può essere utilizzata insieme all'istruzione UPDATE. È possibile aggiornare una o più colonne in una tabella quando si utilizza una sottoquery con l'istruzione UPDATE.

La sintassi di base è la seguente.

UPDATE table
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

Esempio

Supponendo, abbiamo disponibile la tabella CUSTOMERS_BKP che è il backup della tabella CUSTOMERS. L'esempio seguente aggiorna SALARY di 0,25 volte nella tabella CLIENTI per tutti i clienti la cui ETÀ è maggiore o uguale a 27.

SQL> UPDATE CUSTOMERS
   SET SALARY = SALARY * 0.25
   WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
      WHERE AGE >= 27 );

Ciò avrebbe un impatto su due righe e alla fine la tabella CUSTOMERS avrebbe i seguenti record.

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |   125.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  2125.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

Sottoquery con l'istruzione DELETE

La sottoquery può essere utilizzata insieme all'istruzione DELETE come con qualsiasi altra istruzione menzionata sopra.

La sintassi di base è la seguente.

DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

Esempio

Supponendo, abbiamo una tabella CUSTOMERS_BKP disponibile che è un backup della tabella CUSTOMERS. L'esempio seguente elimina i record dalla tabella CUSTOMERS per tutti i clienti la cui ETÀ è maggiore o uguale a 27.

SQL> DELETE FROM CUSTOMERS
   WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
      WHERE AGE >= 27 );

Ciò avrebbe un impatto su due righe e alla fine la tabella CUSTOMERS avrebbe i seguenti record.

+----+----------+-----+---------+----------+
| ID | NAME     | AGE | ADDRESS | SALARY   |
+----+----------+-----+---------+----------+
|  2 | Khilan   |  25 | Delhi   |  1500.00 |
|  3 | kaushik  |  23 | Kota    |  2000.00 |
|  4 | Chaitali |  25 | Mumbai  |  6500.00 |
|  6 | Komal    |  22 | MP      |  4500.00 |
|  7 | Muffy    |  24 | Indore  | 10000.00 |
+----+----------+-----+---------+----------+