Abaixo segue uma explicação resumida e rápida sobre SQL e algumas de suas instruções como SELECT, FROM, WHERE, JOIN, etc. Como já tive várias dúvidas com elas, imagino que outras pessoas possam ter também!
Para ilustração vamos imaginar um banco de dados de uma fornecedora de um produto qualquer, peguemos então duas tabelas: a tabela de produtos e a tabela de pedidos:
Antes de mais nada vamos citar alguns conceitos e termos importantes:
PRIMARY KEY ou CHAVE PRIMÁRIA: identifica o registro (tupla) univocamente, ou seja cada linha terá sua identificação que não poderá se repetir. Nas tabelas acima por exemplo a primary key das tabelas produto e pedido são os campos id, podemos perceber que os valores da coluna id não se repetem.
FOREIGN_KEY ou CHAVE ESTRANGEIRA: faz referência à um atributo de outra tabela, por exemplo na tabela pedido acima existe um campo chamado produto_id que faz referência ao campo id da tabela produto.
Vamos começar então com o código abaixo:
SELECT *
FROM produto, pedido
O resultado da consulta acima será o produto cartesiano das duas tabelas, ou seja teremos uma tabela resultado de 12 registros, 3 registros de produto X 4 registros de pedidos, desta forma vamos ter registros sem lógica, pois apenas fizemos o produto cartesiano das duas tabelas, nada a mais.
Assim, o resultado será o ilustrado abaixo, podemos ver que como estamos usando asterísco (*) na cláusula SELECT, irá aparecer todos os campos das duas tabelas, pois não especificamos nenhum, o asterísco quer dizer TODOS os campos, podemos perceber tambem a falta de lógica dos registro como por exemplo o produto com id 2 junto com o pedido de id 1 que pertence ao produdo de id 1, isso acontece porque o que foi feito foi apenas um produto cartesiano como no esquema ilustrado acima :
Agora vamos fazer uma primeira filtragem, para que possamos ter apenas registros que tenham lógica entre si:
SELECT *
FROM produto AS pr,
pedido AS pd
WHERE pr.id = pd.produto_id
Incluimos agora a instrução WHERE que está fazendo um primeiro filtro, ou seja só está nos mostrando os registro cujo o id da tabela produto seja igual ao id_produto da tabela pedido a cláusula AS indica que daremos um pseudônimo à nossa tabela, desta forma podemos trabalhar com nomes menores. Agora sim podemos ver registros que tenham lógica:
Podemos também fazer a consulta acima usando a instrução JOIN que fará uma combinação das tabelas produto e pedido e depois uma interseção entre as duas tabelas, o resultado será o mesmo do de cima, porém usando o JOIN ganharemos muito mais performance na consulta o que faz muita diferença quando trabalhamos com volumes grandes de registros.
SELECT *
FROM produto AS pr
JOIN pedido AS pd
ON pr.id = pd.produto_id
Abaixo segue ilustração de como podemos exemplicar a consulta usando conjuntos, substituindo os conjuntos pela nossas tabelas fica bastante fácil de se entender!
Agora além de fazermos a interseção das tabelas vamos também fazer uma filtragem que só retorne os registros que contenham no pedido o produto caneta:
SELECT *
FROM produto AS pr
JOIN pedido AS pd
ON pr.id = pd.produto_id
WHERE pr.nome = ‘CANETA’
No código acima estamos selecionando (SELECT) todos os campos (colunas) das tabelas produto e pedido, cujo o id chave primária (PRIMARY KEY) da tabela produto seja igual ao pedido_id que é uma chave estrangeira ( FOREIGN_KEY) na tabela pedido, e ainda que o nome do produto seja “CANETA”.
Neste caso resultado desta consulta seria o seguinte:
Poderiamos ter feito essa mesma consulta da seguinte maneira:
SELECT *
FROM produto AS pr,
pedido AS pd
WHERE pr.id = pd.produto_id AND pr.nome = ‘CANETA’
Desta maneira ele também faria a filtragem assim como o join, porém ele perderia bastante na performance da consulta.
Então desta maneira podemos perceber que no SELECT colocamos os campos que queremos que apareça na consulta (colunas), no caso apresentado acima nós usamos um asterísco (*) então queremos que apareça todos os campos das duas tabelas. No FROM serão colocadas as tableas que queremos consultar, e com o WHERE fazemos as filtragens que forem necessárias.
FUNÇÕES DE AGREGAÇÃO:
COUNT: conta o número de registros do campo passado como parâmetro da consulta.
EX: Contar quantos produtos existem cadastrados na tabela produto.
SELECT COUNT(id) AS qtd_produto
FROM produto;
Resultado:
AVG: média do valor do conjunto do campo passado como parâmetro na consulta.
EX: Fazer a média da quantidade de produto de todos os pedidos feitos.
SELECT AVG(quantidade) AS media_qtd
FROM pedido;
Resultado:
SUM: soma dos valores do conjunto do campo passado como parâmetro.
EX: Saber o total de produtos pedidos.
SELECT SUM(quantidade) AS TOTAL
FROM pedido;
Resultado:
MIN: menor valor do conjunto do campo passado como parâmetro.
EX: O pedido com menor quantidade de produto.
SELECT MIN(quantidade) AS menor_valor
FROM pedido;
Resultado:
MAX: maior valor do conjunto do campo passado como parâmetro.
EX: O pedido com maior quantidade de produto.
SELECT MAX(quantidade) AS maior_valor
FROM pedido;
Resultado:
Agora iremos criar uma nova tabela, a tabela cliente que terá duas colunas o seu id e nome do cliente:
E na tabela pedido vamos adicionar mais uma coluna que será uma chave estrangeira (FOREIGN KEY) que fará referência ao id do cliente. Referenciamos todos os cliente da tabela exceto o cliente de nome Paulo, vamos supor que ele ainda não tenha feito nenhum pedido. E também adicionamos mais um pedido do cliente de id 1 (João).
Vamos imaginar que queremos saber o nome de todos os clientes que fizeram pedido do produto de id 1:
SELECT c.nome
FROM cliente AS c
JOIN pedido AS p
ON c.id = p.cliente_id
WHERE p.produto_id = 1;
O resultado desta consulta será o ilustrado abaixo, podemos perceber que o cliente João aparece duas vezes porque ele fez dois pedidos do produto 1, uma vez com a quantidade de 100 e outra com a quantidade de 300. Porém não precisamos que o nome dele aparece repetidas vezes, senão se um cliente fazer o pedido do mesmo produto 1000 vezes, aparecerá 1000 vezes o nome dele repedido na consulta.
Para resolvermos isto usamos a instrução DISTINCT, ele fará com que não se repita os resultado da consulta:
SELECT DISTINCT(c.nome)
FROM cliente AS c
JOIN pedido AS p
ON c.id = p.cliente_id
WHERE p.produto_id = 1;
Está será a tabela resultado, sem repetições:
Agora supomos que desejamos saber quantos pedidos cada cliente fez, para isso vamos usar a cláusula GROUP BY, que faz o agrupamento de algum paramêtro.
SELECT c.nome, COUNT(p.id) AS Quantidade
FROM cliente AS c
JOIN pedido AS p
ON c.id=p.cliente_id
GROUP BY c.nome;
Acima estamos selecionando o nome do cliente e com a função COUNT estamos contando os pedidos de cada cliente e com o GROUP BY agrupamos por nome do cliente a quantidade de pedidos. Então para cada cliente referenciado na tabela pedido será contado cada pedido que ele fez. A tabela resultado da consulta acima é essa:
SELECT ANINHADO
o selcet aninhado é uma subconsulta, é um comando SELECT embutido em uma outra cláusula SQL.
Imaginemos que gostariamos consultar todos os dados dos clientes que não fizeram nenhum pedido:
SELECT c.*
FROM cliente as c
WHERE c.id NOT IN (
SELECT DISTINCT(c.id)
FROM cliente as c
JOIN pedido as p
ON c.id = p.cliente_id)
Na consulta acima pedimos para que seja mostrados todos os campo da tabela cliente onde o id do cliente não existisse na consulta do segundo SELECT, ou seja, para selicionar todos os atributos da tabela cliente que não existisse na tabela pedido. O resultado seria este:
Apenas o cliente Paulo não fez nenhum pedido ainda!
Referência: Aula de Banco de Dados – Profº Artur – Univás.