Capítulo 3
3- Tabela Derivada
Tabela derivada é um outro nome dado para uma subconsulta.
Uma tabela derivada é uma tabela virtual retornada de uma instrução SELECT.
Uma tabela derivada é semelhante a uma tabela temporária, mas usar uma tabela derivada na instrução SELECT é muito mais simples porque não requer a criação de uma tabela temporária.
Quando uma subconsulta não relacionada (ou independente) é usada na cláusula FROM de uma instrução SELECT, ela também é chamada de tabela derivada. Ou seja, os termos "tabela derivada" e "subconsulta" são freqüentemente usados de forma intercambiável.
O seguinte ilustra uma consulta que usa uma tabela derivada:
Uma subconsulta não-relacionada (também chamada de independente ou autônoma) é uma subconsulta que pode ser executada independentemente da consulta externa.
Ao contrário de uma subconsulta, uma tabela derivada deve ter um apelido (alias) para que você possa fazer referência a seu nome posteriormente na consulta.
Se uma tabela derivada não tiver um al
Every derived table must have its own alias.
Exemplo de Tabela Derivada
Veja no exemplo abaixo uma forma de se usar a tabela derivada. Repare que podemos usá-la numa cláusula WHERE>Exemplo de Uso de Tabela Derivada
SELECT
select_list
FROM
(SELECT
select_list
FROM
table_1) derived_table_name
WHERE
derived_table_name.c1 > 0;
Nos exemplos que se seguem, usamos o banco de dados classicmodels dado no tutorial no qual baseamos essa seção. Veja mais clicando aqui. Ou fazendo o dowload do banco aqui.
Exemplo 1: Criando uma Tabela Derivada
Vamos usar uma consulta como tabela derivada. Primeiro vamos ver a consulta.
A consulta a seguir obtém os cinco produtos principais por receita de vendas em 2003 a partir das tabelas de pedidos e detalhes do pedido no banco de dados de amostra:
Consulta que será usada como tabela derivada
SELECT
productCode,
ROUND(SUM(quantityOrdered * priceEach)) sales
FROM
orderdetails
INNER JOIN
orders USING (orderNumber)
WHERE
YEAR(shippedDate) = 2003
GROUP BY productCode
ORDER BY sales DESC
LIMIT 5;
Usando a Consulta acima como Tabela Derivada
SELECT
productName, sales
FROM
(SELECT
productCode,
ROUND(SUM(quantityOrdered * priceEach)) sales
FROM
orderdetails
INNER JOIN orders USING (orderNumber)
WHERE
YEAR(shippedDate) = 2003
GROUP BY productCode
ORDER BY sales DESC
LIMIT 5) top5products2003
INNER JOIN
products USING (productCode);
Neste exemplo:
Primeiro, a subconsulta é executada para criar um conjunto de resultados ou tabela derivada.
Em seguida, é executada a consulta externa que uniu a tabela derivada top5product2003 com a tabela de produtos usando a coluna productCode.
Clientes Platinum com pedidos com volume superior a 100K.
Clientes Gold com pedidos com volume entre 10K e 100K.
Clientes Silver com pedidos com volume inferior a 10K.
Exemplo 2: Um exemplo mais complexo de tabela derivada
Suponha que você tenha que classificar os clientes que compraram produtos em 2003 em três grupos: platina, ouro e prata. E você precisa saber o número de clientes em cada grupo com as seguintes condições:
Para formar essa consulta, primeiro precisamos colocar cada cliente no respectivo grupo usando a expressão CASE e a cláusula GROUP BY da seguinte maneira:
Uso do CASE para ser usado numa Tabela Derivada
SELECT
customerNumber,
ROUND(SUM(quantityOrdered * priceEach)) sales,
(CASE
WHEN SUM(quantityOrdered * priceEach) < 10000 THEN 'Silver'
WHEN SUM(quantityOrdered * priceEach) BETWEEN 10000 AND 100000 THEN 'Gold'
WHEN SUM(quantityOrdered * priceEach) > 100000 THEN 'Platinum'
END) customerGroup
FROM
orderdetails
INNER JOIN
orders USING (orderNumber)
WHERE
YEAR(shippedDate) = 2003
GROUP BY customerNumber;
Em seguida, podemos usar essa consulta como a tabela derivada e realizar o agrupamento da seguinte maneira:
Consultando Tabela Temporária
SELECT
customerGroup,
COUNT(cg.customerGroup) AS groupCount
FROM
(SELECT
customerNumber,
ROUND(SUM(quantityOrdered * priceEach)) sales,
(CASE
WHEN SUM(quantityOrdered * priceEach) < 10000 THEN 'Silver'
WHEN SUM(quantityOrdered * priceEach) BETWEEN 10000 AND 100000 THEN 'Gold'
WHEN SUM(quantityOrdered * priceEach) > 100000 THEN 'Platinum'
END) customerGroup
FROM
orderdetails
INNER JOIN orders USING (orderNumber)
WHERE
YEAR(shippedDate) = 2003
GROUP BY customerNumber) cg
GROUP BY cg.customerGroup;