Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como trabalhar com subconsultas do MySQL


Uma subconsulta é uma consulta SQL (Structured Query Language) que está aninhada em outra consulta SQL. O comando no qual a subconsulta está aninhada é chamado de consulta pai. As subconsultas são usadas para pré-processar dados usados ​​na consulta pai. As subconsultas podem ser aplicadas em SELECT , INSERT , UPDATE e DELETE operações.

Quando as subconsultas são executadas, a subconsulta é processada primeiro antes da consulta pai. Ao construir aplicativos MySQL, o uso de subconsultas oferece várias vantagens:
  • Eles dividem as instruções SQL em unidades lógicas simples, o que pode torná-las mais fáceis de entender e manter. Em outras palavras, as subconsultas ajudam a isolar partes complexas das consultas.
  • Eles eliminam a necessidade de usarUNION complexos declarações e JOIN declarações.
  • Eles são usados ​​para reforçar a integridade referencial em um cenário em que as chaves estrangeiras não são implementadas.
  • Eles ajudam os desenvolvedores a codificar a lógica de negócios nas consultas do MySQL.

Neste guia você aprenderá:
  • Como usar uma subconsulta correlacionada
  • Como usar uma subconsulta correlacionada em um operador de comparação
  • Como usar uma subconsulta como uma tabela derivada

Antes de começar


Para acompanhar este guia, certifique-se de ter o seguinte:

  1. Se você ainda não o fez, crie uma conta Linode e Compute Instance. Veja nossos guias de Introdução ao Linode e Criação de uma instância de computação.

  2. Siga nosso guia Configurando e protegendo uma instância de computação para atualizar seu sistema. Você também pode definir o fuso horário, configurar seu nome de host, criar uma conta de usuário limitada e proteger o acesso SSH.

  3. O software do servidor MySQL (ou MariaDB) instalado no seu Linode. Consulte a seção MySQL, que contém guias que descrevem como instalar o MySQL em várias distribuições Linux.

Configurando o banco de dados


Para entender como as subconsultas funcionam, primeiro crie um banco de dados de exemplo. Este banco de dados de exemplo é usado para executar as diferentes consultas de exemplo neste guia:

  1. SSH ao seu servidor e faça login no MySQL como root:
     mysql -u root -p
    

    Quando solicitado, digite a senha root do seu servidor MySQL e pressione Enter continuar. Note que a senha root do seu servidor MySQL não é a mesma que a senha root do seu Linode.
    Observação
    Se sua senha não for aceita, talvez seja necessário executar o comando anterior com sudo :
    sudo mysql -u root -p
    

  2. Se sua senha for aceita, você deverá ver o prompt do MySQL:
    
    mysql >
    
    Observação
    Se você estiver usando o MariaDB, poderá ver um prompt como o seguinte:
    
    MariaDB [(none)]>
    

  3. Para criar um banco de dados de amostra chamado test_db , correr:
    CREATE DATABASE test_db;
    

    Você deve ver esta saída, que confirma que o banco de dados foi criado com sucesso:
    
    Query OK, 1 row affected (0.01 sec)
    

  4. Mude para o test_db base de dados:
    USE test_db;
    

    Você deve ver esta saída:
    
    Database changed
    

  5. Você criou o test_db e o selecionou. Em seguida, crie uma tabela chamada customers :
     CREATE TABLE customers
     (
     customer_id BIGINT PRIMARY KEY AUTO_INCREMENT,
     customer_name VARCHAR(50)
     ) ENGINE = InnoDB;
    

    Você deve ver esta saída:
    
    Query OK, 0 rows affected (0.03 sec)
    

  6. Adicione alguns registros aos customers tabela. Execute o INSERT abaixo comandos um por um:
    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');
    

    Esta saída é mostrada após a inserção de cada registro:
    
    Query OK, 1 row affected (0.00 sec)
    ...
    

  7. Verifique se as informações dos clientes foram inseridas no banco de dados. Execute este SELECT comando:
    SELECT * FROM customers;
    

    Você deve ver esta lista de clientes:
    
    +-------------+-----------------+
    | 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. Crie uma sales tabela. Esta tabela usa a coluna customer_id para referenciar os customers tabela:
    CREATE TABLE sales
    (
    order_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    customer_id BIGINT,
    sales_amount DECIMAL(17,2)
    ) ENGINE = InnoDB;
    

    Esta saída aparece:
    
    Query OK, 0 rows affected (0.03 sec)
    

  9. Em seguida, preencha as sales tabela com alguns registros. Execute o INSERT abaixo comandos um por um:
    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');
    

    Esta saída é mostrada após a inserção de cada registro:
    
    Query OK, 1 row affected (0.01 sec)
    ...
    

  10. Verifique os dados em sales tabela. Execute este SELECT comando:
    SELECT * FROM sales;
    

    Esta lista de dados de vendas agora deve ser mostrada:
    
    +----------+-------------+--------------+
    | 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)
    

Depois de configurar o banco de dados e as tabelas relacionadas, agora você pode implementar as diferentes subconsultas no MySQL.

Como usar uma subconsulta correlacionada


Uma subconsulta correlacionada é um tipo de consulta aninhada que usa os valores de uma consulta pai. Esses tipos de consultas fazem referência à consulta pai com uma coluna. A consulta aninhada é executada uma vez para cada linha na consulta pai.

O exemplo abaixo apresenta uma consulta que seleciona todos os clientes. Dentro da consulta, há uma subconsulta correlacionada que busca o valor total de vendas de cada cliente do sales tabela.

  1. Execute a consulta de exemplo:
    SELECT
    customer_id,
    customer_name,
    (SELECT SUM(sales_amount)
    FROM sales WHERE customer_id = customers.customer_id) as total_sales_amount
    FROM
    customers;
    

    Neste exemplo, a subconsulta é SELECT SUM(sales_amount) FROM sales WHERE customer_id = customers.customer_id , que aparece entre parênteses.

    Uma lista do total de vendas feitas pelos clientes é exibida:
    
    +-------------+-----------------+--------------------+
    | 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)
    

    A saída acima da subconsulta correlacionada é capaz de fornecer uma lista resumida dos pedidos dos clientes. Observe, pois customer_id s 3 e 6 não tem nenhum registro associado na tabela de vendas, seu total_sales_amount é NULL .

  2. Uma maneira mais elegante de apresentar esta lista é retornar 0 em vez de NULL para os clientes com vendas zero. Para fazer isso, coloque a saída gerada pela subconsulta com um IFNULL(expression, 0) demonstração. Execute este comando atualizado:
     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;
    

    A seguinte saída é exibida. MySQL retorna 0.00 para todas as linhas que teriam retornado NULL valores.
    
    +-------------+-----------------+--------------------+
    | 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)
    

    Essa abordagem ajuda a garantir que a saída não prejudique nenhum cálculo adicional nos registros.

Como usar uma subconsulta correlacionada em um operador de comparação


As subconsultas são úteis para mover a lógica de negócios para o nível de consulta do banco de dados. Os seguintes casos de uso de negócios apresentam subconsultas correlacionadas colocadas dentro da cláusula WHERE de uma consulta pai:

  • Considere um cenário em que você gostaria de obter uma lista de todos os clientes cadastrados no banco de dados que não possuem vendas associadas. Você pode usar uma subconsulta junto com o operador de comparação MySQL NOT IN e recuperar estes clientes:
      SELECT
      customer_id,
      customer_name
      FROM
      customers
      WHERE customer_id NOT IN (SELECT customer_id FROM sales);
    

    Neste exemplo, a subconsulta é SELECT customer_id FROM sales , que aparece entre parênteses. O comando SQL acima gera uma lista de dois clientes que não são encontrados na tabela de vendas:
    
    +-------------+---------------+
    | customer_id | customer_name |
    +-------------+---------------+
    |           3 | MARY DOE      |
    |           6 | FRANK BRIAN   |
    +-------------+---------------+
    2 rows in set (0.00 sec)
    

    Em um ambiente de produção, você pode usar esse tipo de conjunto de registros para tomar melhores decisões de negócios. Por exemplo, você pode criar um script usando outra linguagem como PHP ou Python para enviar um e-mail a esses clientes e perguntar se eles têm algum problema ao fazer um pedido.

  • Outro caso de uso é na limpeza de dados. Por exemplo, você pode usar uma subconsulta para excluir clientes que nunca fizeram um pedido:
      DELETE
      FROM
      customers
      WHERE customer_id NOT IN (SELECT customer_id FROM sales);
    

    O comando SQL acima exclui os dois clientes e gera o seguinte:
    
    Query OK, 2 rows affected (0.01 sec)
    

    Se você executar um comando para listar todos os clientes novamente, esses clientes não deverão mais aparecer na tabela:
      SELECT *
      FROM
      customers;
    

    A saída abaixo confirma que os clientes sem pedidos associados foram excluídos:
    
    +-------------+-----------------+
    | customer_id | customer_name   |
    +-------------+-----------------+
    |           1 | JOHN PAUL       |
    |           2 | PETER DOE       |
    |           4 | CHRISTINE JAMES |
    |           5 | MARK WELL       |
    +-------------+-----------------+
    4 rows in set (0.00 sec)
    

Como usar uma subconsulta como uma tabela derivada


Quando as subconsultas são usadas no FROM cláusula de uma consulta pai, eles são chamados de tabelas derivadas . Eles são muito importantes ao implementar consultas complexas que, de outra forma, exigiriam um MySQL VIEW , JOIN , ou UNION cláusula. Uma tabela derivada existe na consulta que a criou e não é salva permanentemente no banco de dados.

Quando as subconsultas são usadas como tabelas derivadas, elas isolam as diferentes partes da instrução SQL. Em outras palavras, a subconsulta fornece uma expressão simplificada de uma tabela que pode ser usada no escopo da consulta pai.
Observação Lembre-se, toda tabela derivada deve ter um alias.

Execute o comando abaixo para criar uma subconsulta de tabela derivada com alias como 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;
Observação
Neste comando, a subconsulta aparece entre parênteses como:
SELECT
customer_id,
count(order_id) as total_orders
FROM sales
group by customer_id

O comando acima consulta a tabela de vendas para determinar os clientes com mais de 1 pedido. Quando você executa a consulta, esta saída é exibida:

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

A lista acima mostra quatro customer_id s que têm mais de um pedido. Como exemplo de caso de uso de negócios, você pode usar essa consulta em um script que recompensa os clientes com um bônus em sua próxima compra.

Mais informações


Você pode querer consultar os seguintes recursos para obter informações adicionais sobre este tópico. Embora estes sejam fornecidos na esperança de que sejam úteis, observe que não podemos garantir a precisão ou pontualidade dos materiais hospedados externamente.
  • Subconsultas do MySQL