[SQL deve conhecer e saber] - Lição 11 usando subconsultas

Índice

subconsulta

filtro com subconsulta

Formatar SQL

só pode ser uma única coluna

Subconsultas e desempenho

Usando uma subconsulta como um campo calculado

Nota: nomes de colunas totalmente qualificados

Dica: mais de uma solução


subconsulta

        As instruções SELECT são consultas SQL. Todas as instruções SELECT que vimos até agora foram consultas simples, ou seja, instruções únicas que recuperam dados de uma única tabela de banco de dados.

        O SQL também permite a criação de subconsultas, consultas aninhadas dentro de outras consultas.


filtro com subconsulta

SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num
                    FROM OrderItems
                    WHERE prod_id = 'RGAN01');

        Em uma instrução SELECT, as subconsultas são sempre processadas de dentro para fora. Ao processar a instrução SELECT acima, o DBMS realmente executa duas operações.

        Primeiro, ele executa a seguinte consulta:

SELECT order_num FROM orderitems WHERE prod_id='RGAN01'

        Esta consulta retorna dois números de pedido: 20007 e 20008. Esses dois valores são então passados ​​para a cláusula WHERE da consulta externa no formato separado por vírgula exigido pelo operador IN. A consulta externa se torna:

SELECT cust_id FROM orders WHERE order_num IN (20007,20008)

Formatar SQL

        As instruções SELECT contendo subconsultas são difíceis de ler e depurar, especialmente se forem mais complexas. Conforme mostrado acima, dividir subconsultas em várias linhas e indentá-las apropriadamente pode simplificar bastante o uso de subconsultas.

        A propósito, é aqui que o código de cores entra em jogo, e bons clientes DBMS usam SQL codificado por cores exatamente por esse motivo.

        Pode-se ver que usar subconsultas na cláusula WHERE pode escrever instruções SQL poderosas e flexíveis. Não há limite para o número de subconsultas que podem ser aninhadas, mas devido a limitações de desempenho no uso real, muitas subconsultas não podem ser aninhadas.


só pode ser uma única coluna

        Uma instrução SELECT que é uma subconsulta só pode consultar uma única coluna. As tentativas de recuperar várias colunas retornarão um erro.

SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num, order_id
                    FROM OrderItems
                    WHERE prod_id = 'RGAN01');

        Ocorrerá um erro na instrução acima. Existem duas colunas na subconsulta, mas a condição da consulta externa possui apenas uma coluna. A incompatibilidade causará um erro. Se você deseja corresponder duas colunas, pode escrever da seguinte maneira:

SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num
                    FROM OrderItems
                    WHERE prod_id = 'RGAN01')
AND   order_id IN (SELECT order_id
                    FROM OrderItems
                    WHERE prod_id = 'RGAN01');

Subconsultas e desempenho

        O código fornecido aqui funciona e atinge o resultado desejado. No entanto, usar subconsultas nem sempre é a maneira mais eficiente de realizar esse tipo de recuperação de dados. Para mais discussão, veja a Lição 12, que novamente dá este exemplo.


Usando uma subconsulta como um campo calculado

SELECT cust_name,
        cust_state,
        (SELECT COUNT(*)
        FROM Orders
        WHERE Orders.cust_id = Customers.cust_id) AS orders
FROM Customers
ORDER BY cust_name;

        Essa instrução SELECT retorna três colunas para cada cliente na tabela Clientes: cust_name, cust_state e orders. orders é um campo computado criado a partir da subconsulta entre parênteses. Essa subconsulta é executada uma vez para cada cliente recuperado. Nesse caso, a subconsulta é executada 5 vezes porque 5 clientes foram recuperados.

        A cláusula WHERE na subconsulta é um pouco diferente da cláusula WHERE usada anteriormente, pois usa o nome completo da coluna em vez de apenas o nome da coluna ( cust_id ). Ele especifica os nomes de tabela e coluna (Orders.cust_id e Customers.cust_id). A seguinte cláusula WHERE diz ao SQL para comparar o cust_id na tabela Orders com o cust_id que está sendo recuperado da tabela Customers:

WHERE Orders.cust_id = Customers.cust_id

        Separe os nomes das tabelas e colunas com um ponto, esta sintaxe deve ser usada quando houver a possibilidade de confundir os nomes das colunas. Neste exemplo, há duas colunas cust_id: uma em Clientes e outra em Pedidos. Sem qualificar totalmente os nomes das colunas, o DBMS pensaria que o cust_id na tabela Orders estava sendo comparado a si mesmo. porque

SELECT COUNT(*) FROM Orders WHERE cust_id = cust_id

        sempre retorna o número total de pedidos da tabela Orders, o que não é o que queremos:

SELECT cust_name,
    cust_state,
    (SELECT COUNT(*)
    FROM Orders
    WHERE cust_id = cust_id) AS orders
FROM Customers
ORDER BY cust_name;

        Embora subconsultas sejam extremamente úteis na construção de tais instruções SELECT, deve-se tomar cuidado para limitar colunas ambíguas.

        Você também pode usar a forma de aliases de tabela para distinguir campos, por exemplo, alias a para a tabela 1 e alias b para a tabela 2 e usar a.field = b.field para distinguir nomes de campo.


Nota: nomes de colunas totalmente qualificados

        Você já viu por que deve usar nomes de coluna totalmente qualificados e retornar resultados falsos se não os especificar, porque o DBMS interpretará mal o que você quis dizer. Às vezes, o DBMS lança uma mensagem de erro devido à ambigüidade causada por nomes de colunas conflitantes. Por exemplo, um nome de coluna especificado por uma cláusula WHERE ou ORDER BY pode aparecer em mais de uma tabela. É uma boa prática usar nomes de coluna totalmente qualificados para evitar ambigüidade ao operar em várias tabelas em uma instrução SELECT.


Dica: mais de uma solução

        Conforme mencionado anteriormente nesta lição, embora o código de exemplo apresentado aqui funcione bem, não é a maneira mais eficiente de resolver esse tipo de recuperação de dados. Encontraremos esse exemplo novamente quando estudarmos JOINs nas próximas duas lições.

Acho que você gosta

Origin blog.csdn.net/qq_57163366/article/details/130007545
Recomendado
Clasificación