Mysql
 sql >> Database >  >> RDS >> Mysql

Come lavorare con le sottoquery MySQL

Una sottoquery è una query SQL (Structured Query Language) nidificata all'interno di un'altra query SQL. Il comando in cui è nidificata la sottoquery viene definito query padre. Le sottoquery vengono utilizzate per pre-elaborare i dati utilizzati nella query padre. Le sottoquery possono essere applicate in SELECT , INSERT , UPDATE e DELETE operazioni.

Quando vengono eseguite sottoquery, la sottoquery viene elaborata prima della query padre. Quando si creano applicazioni MySQL, l'utilizzo di sottoquery offre numerosi vantaggi:

  • Rompono le istruzioni SQL in semplici unità logiche, che possono renderle più facili da comprendere e mantenere. In altre parole, le sottoquery aiutano a isolare parti complesse delle query.
  • Eliminano la necessità di utilizzare UNION complessi dichiarazioni e JOIN dichiarazioni.
  • Sono utilizzati per imporre l'integrità referenziale in uno scenario in cui le chiavi esterne non vengono implementate.
  • Aiutano gli sviluppatori a codificare la logica aziendale nelle query MySQL.

In questa guida imparerai:

  • Come utilizzare una sottoquery correlata
  • Come utilizzare una sottoquery correlata in un operatore di confronto
  • Come utilizzare una sottoquery come tabella derivata

Prima di iniziare

Per seguire questa guida, assicurati di avere quanto segue:

  1. Se non l'hai già fatto, crea un account Linode e un'istanza di calcolo. Consulta le nostre guide Introduzione a Linode e Creazione di un'istanza di calcolo.

  2. Segui la nostra guida alla configurazione e alla protezione di un'istanza di calcolo per aggiornare il tuo sistema. Potresti anche voler impostare il fuso orario, configurare il tuo nome host, creare un account utente limitato e rafforzare l'accesso SSH.

  3. Il software del server MySQL (o MariaDB) installato sul tuo Linode. Fare riferimento alla sezione MySQL, che contiene guide che descrivono come installare MySQL su diverse distribuzioni Linux.

Configurazione del database

Per comprendere come funzionano le sottoquery, creare prima un database di esempio. Questo database di esempio viene utilizzato per eseguire le diverse query di esempio in questa guida:

  1. SSH sul tuo server e accedi a MySQL come root:

     mysql -u root -p
    

    Quando richiesto, inserisci la password di root del tuo server MySQL e premi Invio continuare. Nota che la password di root del tuo server MySQL non è la stessa della password di root per il tuo Linode.

    Nota

    Se la tua password non viene accettata, potresti dover eseguire il comando precedente con sudo :

    sudo mysql -u root -p
    
  2. Se la tua password viene accettata, dovresti vedere il prompt di MySQL:

    
    mysql >
    
    Nota

    Se stai usando MariaDB, potresti invece visualizzare un messaggio come il seguente:

    
    MariaDB [(none)]>
    
  3. Per creare un database di esempio denominato test_db , esegui:

    CREATE DATABASE test_db;
    

    Dovresti vedere questo output, che conferma che il database è stato creato correttamente:

    
    Query OK, 1 row affected (0.01 sec)
    
  4. Passa a test_db banca dati:

    USE test_db;
    

    Dovresti vedere questo output:

    
    Database changed
    
  5. Hai creato il test_db e l'ho selezionato. Quindi, crea una tabella denominata customers :

     CREATE TABLE customers
     (
     customer_id BIGINT PRIMARY KEY AUTO_INCREMENT,
     customer_name VARCHAR(50)
     ) ENGINE = InnoDB;
    

    Dovresti vedere questo output:

    
    Query OK, 0 rows affected (0.03 sec)
    
  6. Aggiungi alcuni record ai customers tavolo. Esegui il seguente INSERT comandi uno per uno:

    INSERT INTO customers(customer_name) VALUES ('JOHN PAUL');
    INSERT INTO customers(customer_name) VALUES ('PETER DOE');
    INSERT INTO customers(customer_name) VALUES ('MARY DOE');
    INSERT INTO customers(customer_name) VALUES ('CHRISTINE JAMES');
    INSERT INTO customers(customer_name) VALUES ('MARK WELL');
    INSERT INTO customers(customer_name) VALUES ('FRANK BRIAN');
    

    Questo output viene mostrato dopo l'inserimento di ogni record:

    
    Query OK, 1 row affected (0.00 sec)
    ...
    
  7. Verificare che le informazioni sui clienti siano state inserite nel database. Esegui questo SELECT comando:

    SELECT * FROM customers;
    

    Dovresti vedere questo elenco di clienti:

    
    +-------------+-----------------+
    | customer_id | customer_name   |
    +-------------+-----------------+
    |           1 | JOHN PAUL       |
    |           2 | PETER DOE       |
    |           3 | MARY DOE        |
    |           4 | CHRISTINE JAMES |
    |           5 | MARK WELL       |
    |           6 | FRANK BRIAN     |
    +-------------+-----------------+
    6 rows in set (0.00 sec)
    
  8. Crea un sales tavolo. Questa tabella utilizza la colonna customer_id per fare riferimento ai customers tabella:

    CREATE TABLE sales
    (
    order_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    customer_id BIGINT,
    sales_amount DECIMAL(17,2)
    ) ENGINE = InnoDB;
    

    Viene visualizzato questo output:

    
    Query OK, 0 rows affected (0.03 sec)
    
  9. Quindi, compila le sales tabella con alcuni record. Esegui il seguente INSERT comandi uno per uno:

    INSERT INTO sales (customer_id, sales_amount) VALUES ('1','25.75');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('2','85.25');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('5','3.25');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('4','200.75');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('5','88.10');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('1','100.00');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('2','45.00');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('4','15.80');
    

    Questo output viene mostrato dopo l'inserimento di ogni record:

    
    Query OK, 1 row affected (0.01 sec)
    ...
    
  10. Verifica i dati nelle sales tavolo. Esegui questo SELECT comando:

    SELECT * FROM sales;
    

    Questo elenco di dati di vendita dovrebbe ora essere mostrato:

    
    +----------+-------------+--------------+
    | order_id | customer_id | sales_amount |
    +----------+-------------+--------------+
    |        1 |           1 |        25.75 |
    |        2 |           2 |        85.25 |
    |        3 |           5 |         3.25 |
    |        4 |           4 |       200.75 |
    |        5 |           5 |        88.10 |
    |        6 |           1 |       100.00 |
    |        7 |           2 |        45.00 |
    |        8 |           4 |        15.80 |
    +----------+-------------+--------------+
    8 rows in set (0.00 sec)
    

Dopo aver impostato il database e le relative tabelle, ora puoi implementare le diverse sottoquery in MySQL.

Come utilizzare una sottoquery correlata

Una sottoquery correlata è un tipo di query nidificata che utilizza i valori di una query padre. Questi tipi di query fanno riferimento alla query padre con una colonna. La query nidificata viene eseguita una volta per ogni riga nella query padre.

L'esempio seguente presenta una query che seleziona tutti i clienti. All'interno della query è presente una sottoquery correlata che recupera l'importo totale delle vendite per ciascun cliente dalle sales tabella.

  1. Esegui la query di esempio:

    SELECT
    customer_id,
    customer_name,
    (SELECT SUM(sales_amount)
    FROM sales WHERE customer_id = customers.customer_id) as total_sales_amount
    FROM
    customers;
    

    In questo esempio, la sottoquery è SELECT SUM(sales_amount) FROM sales WHERE customer_id = customers.customer_id , che appare tra parentesi.

    Viene visualizzato un elenco delle vendite totali effettuate dai clienti:

    
    +-------------+-----------------+--------------------+
    | customer_id | customer_name   | total_sales_amount |
    +-------------+-----------------+--------------------+
    |           1 | JOHN PAUL       |             125.75 |
    |           2 | PETER DOE       |             130.25 |
    |           3 | MARY DOE        |               NULL |
    |           4 | CHRISTINE JAMES |             216.55 |
    |           5 | MARK WELL       |              91.35 |
    |           6 | FRANK BRIAN     |               NULL |
    +-------------+-----------------+--------------------+
    6 rows in set (0.00 sec)
    

    L'output sopra della subquery correlata è in grado di fornire un elenco riepilogativo degli ordini dei clienti. Nota, poiché customer_id s 3 e 6 non hanno record associati nella tabella delle vendite, il loro total_sales_amount è NULL .

  2. Un modo più elegante per presentare questo elenco è restituire 0 invece di NULL per i clienti con zero vendite. Per fare ciò, racchiudere l'output generato dalla sottoquery con un IFNULL(expression, 0) dichiarazione. Esegui questo comando aggiornato:

     SELECT
     customer_id,
     customer_name,
     IFNULL((SELECT SUM(sales_amount)
     FROM sales WHERE customer_id = customers.customer_id), 0) as total_sales_amount
     FROM
     customers;
    

    Viene visualizzato il seguente output. MySQL restituisce 0.00 per tutte le righe che altrimenti avrebbero restituito NULL valori.

    
    +-------------+-----------------+--------------------+
    | customer_id | customer_name   | total_sales_amount |
    +-------------+-----------------+--------------------+
    |           1 | JOHN PAUL       |             125.75 |
    |           2 | PETER DOE       |             130.25 |
    |           3 | MARY DOE        |               0.00 |
    |           4 | CHRISTINE JAMES |             216.55 |
    |           5 | MARK WELL       |              91.35 |
    |           6 | FRANK BRIAN     |               0.00 |
    +-------------+-----------------+--------------------+
    6 rows in set (0.00 sec)
    

    Questo approccio aiuta a garantire che l'output non danneggi ulteriori calcoli sui record.

Come utilizzare una sottoquery correlata in un operatore di confronto

Le sottoquery sono utili per spostare la logica aziendale nel livello di query del database. I seguenti casi d'uso aziendali presentano sottoquery correlate poste all'interno della clausola WHERE di una query principale:

  • Considera uno scenario in cui desideri ottenere un elenco di tutti i clienti registrati nel database che non hanno vendite associate. Puoi usare una sottoquery insieme all'operatore di confronto MySQL NOT IN e recuperare questi clienti:

      SELECT
      customer_id,
      customer_name
      FROM
      customers
      WHERE customer_id NOT IN (SELECT customer_id FROM sales);
    

    In questo esempio, la sottoquery è SELECT customer_id FROM sales , che appare tra parentesi. Il comando SQL precedente restituisce un elenco di due clienti che non si trovano nella tabella delle vendite:

    
    +-------------+---------------+
    | customer_id | customer_name |
    +-------------+---------------+
    |           3 | MARY DOE      |
    |           6 | FRANK BRIAN   |
    +-------------+---------------+
    2 rows in set (0.00 sec)
    

    In un ambiente di produzione, è possibile utilizzare questo tipo di recordset per prendere decisioni aziendali migliori. Ad esempio, puoi creare uno script utilizzando un altro linguaggio come PHP o Python per inviare un'e-mail a questi clienti e chiedere se hanno problemi a effettuare un ordine.

  • Un altro caso d'uso è nella pulizia dei dati. Ad esempio, puoi utilizzare una sottoquery per eliminare i clienti che non hanno mai effettuato un ordine:

      DELETE
      FROM
      customers
      WHERE customer_id NOT IN (SELECT customer_id FROM sales);
    

    Il comando SQL precedente elimina i due clienti e restituisce quanto segue:

    
    Query OK, 2 rows affected (0.01 sec)
    

    Se esegui un comando per elencare nuovamente tutti i clienti, questi clienti non dovrebbero più essere visualizzati nella tabella:

      SELECT *
      FROM
      customers;
    

    L'output seguente conferma che i clienti senza ordini associati sono stati eliminati:

    
    +-------------+-----------------+
    | customer_id | customer_name   |
    +-------------+-----------------+
    |           1 | JOHN PAUL       |
    |           2 | PETER DOE       |
    |           4 | CHRISTINE JAMES |
    |           5 | MARK WELL       |
    +-------------+-----------------+
    4 rows in set (0.00 sec)
    

Come utilizzare una sottoquery come tabella derivata

Quando le sottoquery vengono utilizzate nel FROM clausola di una query padre, sono denominate tabelle derivate . Sono molto importanti quando si implementano query complesse che altrimenti richiederebbero una VIEW MySQL , JOIN o UNION clausola. Una tabella derivata esiste nella query che l'ha creata e non viene salvata in modo permanente nel database.

Quando le sottoquery vengono utilizzate come tabelle derivate, isolano le diverse parti dell'istruzione SQL. In altre parole, la sottoquery fornisce un'espressione semplificata di una tabella che può essere utilizzata nell'ambito della query padre.

Nota Ricorda, ogni tabella derivata deve avere un alias.

Esegui il comando seguente per creare una sottoquery di tabella derivata con alias order_summary :

SELECT customer_id
FROM
    (
    SELECT
    customer_id,
    count(order_id) as total_orders
    FROM sales
    group by customer_id
    ) as order_summary
WHERE order_summary.total_orders > 1;
Nota

In questo comando, la sottoquery appare tra parentesi come:

SELECT
customer_id,
count(order_id) as total_orders
FROM sales
group by customer_id

Il comando precedente interroga la tabella delle vendite per determinare i clienti con più di 1 ordine. Quando esegui la query, viene visualizzato questo output:


+-------------+
| customer_id |
+-------------+
|           1 |
|           2 |
|           5 |
|           4 |
+-------------+
4 rows in set (0.00 sec)

L'elenco sopra mostra quattro customer_id s che hanno più di un ordine. Come esempio di caso d'uso aziendale, puoi utilizzare tale query in uno script che premia i clienti con un bonus al loro prossimo acquisto.

Maggiori informazioni

Si consiglia di consultare le seguenti risorse per ulteriori informazioni su questo argomento. Sebbene questi siano forniti nella speranza che possano essere utili, tieni presente che non possiamo garantire l'accuratezza o la tempestività dei materiali ospitati esternamente.

  • Sottoquery MySQL