2. Junções
As junções (joins) são ferramentas presentes na maioria dos bancos
de dados que suportam SQL e são usadas quando precisamos
recuperar dados de uma ou mais tabelas com base em suas relações
lógicas. Desta forma, é possível combinar os registros de tais tabelas
de forma a construir um “super registro”, que nos permitirá exibir
relatórios mais elaborados.
3. Junções
Para o bom entendimento de junções, vamos considerar duas
tabelas: filmes e generos. Aqui nós temos uma cardinalidade de 1 x
N. Um filme possui um gênero, enquanto um gênero pode abranger
vários filmes. Vamos começar criando estas duas tabelas (comece
com a tabela generos, já que esta não depende da tabela de filmes):
4. Junções
Comando DLL CREATE TABLE para a tabela generos:
CREATE TABLE generos(
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
nome VARCHAR(45) NOT NULL,
PRIMARY KEY(id)
)
ENGINE = InnoDB;
5. Junções
Comando DLL CREATE TABLE para a tabela filmes:
CREATE TABLE filmes(
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
titulo VARCHAR(45) NOT NULL,
genero INTEGER UNSIGNED NOT NULL,
PRIMARY KEY(id),
CONSTRAINT fk_filmes_generos FOREIGN KEY
fk_filmes_generos(id)
REFERENCES generos(id) ON DELETE RESTRICT ON
UPDATE RESTRICT
)
ENGINE = InnoDB;
6. Junções
Veja que a tabela filmes contém uma chave estrangeira
referenciando a chave primária da tabela generos. Isso nos permite
“atrelar” um filme ao seu gênero. Após inserir dados na tabela
generos e na tabela filme, observe o resultado de um comando DML
SELECT na tabela filmes:
7. Junções
SELECT * FROM filmes;
id titulo genero
1 EFEITO BORBOLETA 6
2 O PENTELHO 1
3 VIAGEM MALDITA 3
Nesta query o gênero é retornado como um valor inteiro, ou seja, o
valor do campo id da tabela generos. Em muitos casos este não é o
comportamento que queremos. Em vez do id do gênero nós
gostaríamos de exibir seu nome. Isso pode ser conseguido da
seguinte forma:
8. Junções
SELECT filmes.id, filmes.titulo, generos.nome FROM filmes,
generos WHERE filmes.genero = generos.id;
id titulo genero
1 EFEITO BORBOLETA FICÇÃO
2 O PENTELHO COMÉDIA
3 VIAGEM MALDITA TERROR
Nesta query eu usei o nome completo da tabela antes do nome dos
campos a serem retornados. Na prática, é comum darmos apelidos
às tabelas. Veja:
SELECT f.id, f.titulo, g.nome FROM filmes f, generos g WHERE
f.genero = g.id;
9. Subconsultas
Uma subconsulta é uma instrução SELECT adicionada dentro de
uma instrução SELECT, SELECT...INTO, INSERT...INTO,
DELETE, ou UPDATE ou dentro de outra subconsulta. Pode
utilizar três formas de sintaxe para criar uma subconsulta:
10. Subconsultas
comparação [ANY | ALL | SOME] (instrução sql) expressão
[NOT] IN (instrução sql) [NOT] EXISTS (instrução sql)
Onde:
Comparação: É uma expressão e um operador de comparação que
compara a expressão com o resultado da subconsulta.
Expressão: É uma expressão pela qual se busca o conjunto
resultante da subconsulta.
Instrução SQL: É uma instrução SELECT, que segue o mesmo
formato e regras que qualquer outra SELECT. Deve ir entre
parênteses.
11. Subconsultas
Pode-se utilizar uma subconsulta no lugar de uma expressão na lista
de campos de uma instrução SELECT ou em uma cláusula WHERE
ou HAVING. Em uma subconsulta, se utiliza uma instrução
SELECT para proporcionar um conjunto de um ou mais valores
especificados para avaliar na expressão da cláusula WHERE ou
HAVING.
12. Subconsultas
Pode-se utilizar o predicado ANY ou SOME, os quais são
sinônimos, para recuperar registros da consulta principal, que
satisfaçam a comparação com qualquer outro registro recuperado na
subconsulta. O exemplo seguinte devolve todos os produtos cujo
preço unitário for maior que o de qualquer produto vendido com um
desconto igual ou maior ao 25 por cento:
13. Subconsultas
SELECT *
FROM
Produtos
WHERE
PrecoUnidade >=
ANY
(
SELECT
PrecoUnidade
FROM
DetalhePedido
WHERE
Desconto = 0 .25
)
14. Subconsultas
O predicado ALL se utiliza para recuperar unicamente aqueles
registros da consulta principal que satisfazem a comparação com
todos os registros recuperados na subconsulta. Se se muda ANY por
ALL no exemplo anterior, a consulta devolverá unicamente aqueles
produtos cujo preço unitário for maior que o de todos os produtos
vendidos com um desconto igual ou maior ao 25 por cento. Isto é
muito mais restritivo.
15. Subconsultas
O predicado IN se emprega para recuperar unicamente aqueles
registros da consulta principal para os que alguns registros da
subconsulta contém um valor igual. O exemplo seguinte devolve
todos os produtos vendidos com um desconto igual a 25 por cento:
16. Subconsultas
SELECT *
FROM
Produtos
WHERE
IDProduto
IN
(
SELECT
IDProduto
FROM
DetalhePedido
WHERE
Desconto = 0.25
)
17. Subconsultas
Inversamente, pode-se utilizar NOT IN para recuperar unicamente
aqueles registros da consulta principal para os que não têm nenhum
registro da subconsulta que contenha um valor igual.
O predicado EXISTS (com palavra reservada NOT opcional) se
utiliza em comparações de verdade/falso para determinar se a
subconsulta devolve algum registro. Suponhamos que desejamos
recuperar todos aqueles clientes que tiverem realizado pelo menos
um pedido:
18. Subconsultas
SELECT
Clientes.Companhia, Clientes.Telefone
FROM
Clientes
WHERE EXISTS (
SELECT
FROM
Pedidos
WHERE
Pedidos.IdPedido = Clientes.IdCliente
)