Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment travailler avec les sous-requêtes MySQL

Une sous-requête est une requête SQL (Structured Query Language) imbriquée dans une autre requête SQL. La commande dans laquelle la sous-requête est imbriquée est appelée requête parent. Les sous-requêtes sont utilisées pour prétraiter les données utilisées dans la requête parent. Les sous-requêtes peuvent être appliquées dans SELECT , INSERT , UPDATE , et DELETE opérations.

Lorsque des sous-requêtes sont exécutées, la sous-requête est traitée en premier avant la requête parent. Lors de la création d'applications MySQL, l'utilisation de sous-requêtes offre plusieurs avantages :

  • Ils décomposent les instructions SQL en unités logiques simples, ce qui peut faciliter leur compréhension et leur maintenance. En d'autres termes, les sous-requêtes aident à isoler les parties complexes des requêtes.
  • Ils éliminent le besoin d'utiliser des UNION complexes déclarations et JOIN déclarations.
  • Ils sont utilisés pour renforcer l'intégrité référentielle dans un scénario où les clés étrangères ne sont pas implémentées.
  • Ils aident les développeurs à coder la logique métier dans les requêtes MySQL.

Dans ce guide, vous apprendrez :

  • Comment utiliser une sous-requête corrélée
  • Comment utiliser une sous-requête corrélée dans un opérateur de comparaison
  • Comment utiliser une sous-requête en tant que table dérivée

Avant de commencer

Pour suivre ce guide, assurez-vous d'avoir les éléments suivants :

  1. Si vous ne l'avez pas déjà fait, créez un compte Linode et une instance de calcul. Consultez nos guides Premiers pas avec Linode et Création d'une instance de calcul.

  2. Suivez notre guide Configuration et sécurisation d'une instance de calcul pour mettre à jour votre système. Vous pouvez également définir le fuseau horaire, configurer votre nom d'hôte, créer un compte utilisateur limité et renforcer l'accès SSH.

  3. Le logiciel serveur MySQL (ou MariaDB) installé sur votre Linode. Veuillez vous référer à la section MySQL, qui contient des guides décrivant comment installer MySQL sur plusieurs distributions Linux.

Configuration de la base de données

Pour comprendre le fonctionnement des sous-requêtes, créez d'abord un exemple de base de données. Cet exemple de base de données est utilisé pour exécuter les différents exemples de requêtes de ce guide :

  1. SSH à votre serveur et connectez-vous à MySQL en tant que root :

     mysql -u root -p
    

    Lorsque vous y êtes invité, entrez le mot de passe root de votre serveur MySQL et appuyez sur Entrée continuer. Notez que le mot de passe root de votre serveur MySQL n'est pas le même que le mot de passe root de votre Linode.

    Remarque

    Si votre mot de passe n'est pas accepté, vous devrez peut-être exécuter la commande précédente avec sudo :

    sudo mysql -u root -p
    
  2. Si votre mot de passe est accepté, vous devriez voir l'invite MySQL :

    
    mysql >
    
    Remarque

    Si vous utilisez MariaDB, vous pouvez voir une invite comme celle-ci à la place :

    
    MariaDB [(none)]>
    
  3. Pour créer un exemple de base de données nommé test_db , exécutez :

    CREATE DATABASE test_db;
    

    Vous devriez voir cette sortie, qui confirme que la base de données a été créée avec succès :

    
    Query OK, 1 row affected (0.01 sec)
    
  4. Basculer vers test_db base de données :

    USE test_db;
    

    Vous devriez voir cette sortie :

    
    Database changed
    
  5. Vous avez créé le test_db et l'a sélectionné. Ensuite, créez une table nommée customers :

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

    Vous devriez voir cette sortie :

    
    Query OK, 0 rows affected (0.03 sec)
    
  6. Ajouter des enregistrements aux customers table. Exécutez le INSERT ci-dessous commandes une par une :

    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');
    

    Cette sortie s'affiche après l'insertion de chaque enregistrement :

    
    Query OK, 1 row affected (0.00 sec)
    ...
    
  7. Vérifiez que les informations des clients ont été insérées dans la base de données. Exécutez ce SELECT commande :

    SELECT * FROM customers;
    

    Vous devriez voir cette liste de clients :

    
    +-------------+-----------------+
    | 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. Créer un sales table. Ce tableau utilise la colonne customer_id pour référencer les customers tableau :

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

    Cette sortie apparaît :

    
    Query OK, 0 rows affected (0.03 sec)
    
  9. Ensuite, remplissez le champ sales tableau avec quelques enregistrements. Exécutez le INSERT ci-dessous commandes une par une :

    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');
    

    Cette sortie s'affiche après l'insertion de chaque enregistrement :

    
    Query OK, 1 row affected (0.01 sec)
    ...
    
  10. Vérifiez les données dans les sales table. Exécutez ce SELECT commande :

    SELECT * FROM sales;
    

    Cette liste de données de ventes devrait maintenant s'afficher :

    
    +----------+-------------+--------------+
    | 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)
    

Après avoir configuré la base de données et les tables associées, vous pouvez maintenant implémenter les différentes sous-requêtes dans MySQL.

Comment utiliser une sous-requête corrélée

Une sous-requête corrélée est un type de requête imbriquée qui utilise les valeurs d'une requête parent. Ces types de requêtes font référence à la requête parent avec une colonne. La requête imbriquée est exécutée une fois pour chaque ligne de la requête parent.

L'exemple ci-dessous présente une requête qui sélectionne tous les clients. À l'intérieur de la requête, il y a une sous-requête corrélée qui récupère le montant total des ventes pour chaque client à partir des sales tableau.

  1. Exécutez l'exemple de requête :

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

    Dans cet exemple, la sous-requête est SELECT SUM(sales_amount) FROM sales WHERE customer_id = customers.customer_id , qui apparaît entre parenthèses.

    Une liste des ventes totales réalisées par les clients s'affiche :

    
    +-------------+-----------------+--------------------+
    | 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)
    

    La sortie ci-dessus de la sous-requête corrélée peut vous donner une liste résumée des commandes des clients. Veuillez noter que depuis customer_id s 3 et 6 n'ont aucun enregistrement associé dans la table des ventes, leur total_sales_amount est NULL .

  2. Une façon plus élégante de présenter cette liste est de renvoyer 0 au lieu de NULL pour les clients avec zéro vente. Pour ce faire, entourez la sortie générée par la sous-requête d'un IFNULL(expression, 0) déclaration. Exécutez cette commande mise à jour :

     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;
    

    La sortie suivante apparaît. MySQL renvoie 0,00 pour toutes les lignes qui auraient autrement renvoyé NULL valeurs.

    
    +-------------+-----------------+--------------------+
    | 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)
    

    Cette approche permet de s'assurer que la sortie ne nuit pas aux calculs ultérieurs sur les enregistrements.

Comment utiliser une sous-requête corrélée dans un opérateur de comparaison

Les sous-requêtes sont utiles pour déplacer la logique métier au niveau de la requête de la base de données. Les cas d'utilisation métier suivants présentent des sous-requêtes corrélées placées dans la clause WHERE d'une requête parent :

  • Considérez un scénario dans lequel vous souhaitez obtenir une liste de tous les clients enregistrés dans la base de données qui n'ont pas de ventes associées. Vous pouvez utiliser une sous-requête avec l'opérateur de comparaison MySQL NOT IN et récupérer ces clients :

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

    Dans cet exemple, la sous-requête est SELECT customer_id FROM sales , qui apparaît entre parenthèses. La commande SQL ci-dessus génère une liste de deux clients introuvables dans la table des ventes :

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

    Dans un environnement de production, vous pouvez utiliser ce type de jeu d'enregistrements pour prendre de meilleures décisions commerciales. Par exemple, vous pouvez créer un script utilisant un autre langage comme PHP ou Python pour envoyer un e-mail à ces clients et leur demander s'ils ont un problème pour passer une commande.

  • Un autre cas d'utilisation concerne le nettoyage des données. Par exemple, vous pouvez utiliser une sous-requête pour supprimer les clients qui n'ont jamais passé de commande :

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

    La commande SQL ci-dessus supprime les deux clients et affiche ce qui suit :

    
    Query OK, 2 rows affected (0.01 sec)
    

    Si vous exécutez à nouveau une commande pour répertorier tous les clients, ces clients ne devraient plus apparaître dans le tableau :

      SELECT *
      FROM
      customers;
    

    La sortie ci-dessous confirme que les clients sans commandes associées ont été supprimés :

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

Comment utiliser une sous-requête comme table dérivée

Lorsque des sous-requêtes sont utilisées dans le FROM clause d'une requête parent, elles sont appelées tables dérivées . Ils sont très importants lors de la mise en œuvre de requêtes complexes qui nécessiteraient autrement une MySQL VIEW , JOIN , ou UNION clause. Une table dérivée existe dans la requête qui l'a créée et n'est pas enregistrée de manière permanente dans la base de données.

Lorsque des sous-requêtes sont utilisées comme tables dérivées, elles isolent les différentes parties de l'instruction SQL. En d'autres termes, la sous-requête fournit une expression simplifiée d'une table qui peut être utilisée dans le cadre de la requête parent.

Remarque N'oubliez pas que chaque table dérivée doit avoir un alias.

Exécutez la commande ci-dessous pour créer une sous-requête de table dérivée dont l'alias est 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;
Remarque

Dans cette commande, la sous-requête apparaît entre parenthèses comme :

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

La commande ci-dessus interroge la table des ventes pour déterminer les clients avec plus d'une commande. Lorsque vous exécutez la requête, cette sortie apparaît :


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

La liste ci-dessus montre quatre customer_id s qui ont plus d'une commande. Comme exemple de cas d'utilisation commerciale, vous pouvez utiliser une telle requête dans un script qui récompense les clients avec un bonus sur leur prochain achat.

Plus d'informations

Vous pouvez consulter les ressources suivantes pour plus d'informations sur ce sujet. Bien que ceux-ci soient fournis dans l'espoir qu'ils seront utiles, veuillez noter que nous ne pouvons pas garantir l'exactitude ou l'actualité des documents hébergés en externe.

  • Sous-requêtes MySQL