Freqüentemente, ao usar SQL para amostrageminformações das tabelas, o usuário recebe dados redundantes que consistem na presença de linhas repetidas absolutamente idênticas. Para evitar essa situação, use o argumento SQL distinto na cláusula Select. Este artigo examinará exemplos de uso desse argumento, bem como situações em que é melhor recusar-se a usá-lo.
Antes de começarmos a examinar exemplos específicos, vamos criar algumas tabelas obrigatórias no banco de dados.
Vamos imaginar que nosso banco de dados armazenainformações sobre papel de parede apresentadas em duas tabelas. Trata-se de uma tabela Oboi (papel de parede) com os campos id (identificador único), tipo (tipo de papel de parede - papel, vinil, etc.), cor (cor), estrutura (estrutura) e preço (preço). E a tabela Ostatki (sobras) com os campos id_oboi (link para o identificador único na tabela Oboi) e contagem (o número de rolos no armazém).
Vamos preencher as tabelas com dados. Adicione 9 entradas à mesa do papel de parede:
Oboi | ||||
Eu iria | tipo | cor | estrutura | preço |
1 | Papel | Multicolorido | Em relevo | 56,9 |
2 | Duas camadas de papel | Bege | Suave | 114,8 |
3 | Vinil | laranja | Em relevo | 504 |
4 | Não tecido | Bege | Em relevo | 1020,9 |
5 | Duas camadas de papel | Bege | Suave | 150,6 |
6 | Papel | Multicolorido | Suave | 95,4 |
7 | Vinil | Castanho | Suave | 372 |
8 | Não tecido | Brancos | Em relevo | 980,1 |
9 | Tecido | Rosa | Suave | 1166,5 |
Existem também nove entradas na tabela com resíduos:
Ostatki | |
id_oboi | contagem |
1 | 8 |
2 | 12 |
3 | 24 |
4 | 9 |
5 | 16 |
6 | 7 |
7 | 24 |
8 | 32 |
9 | 11 |
Vamos começar a descrever como o distinto é usado em SQL.
Distinto deve ser colocado imediatamente apósSelecione a palavra-chave nas consultas. Ele é aplicado imediatamente a todas as colunas especificadas na cláusula Select, porque excluirá linhas absolutamente idênticas do resultado final da consulta. Portanto, é suficiente especificar “select distintos” uma vez ao escrever uma consulta SQL. Uma exceção é o uso de funções de agregação distintas, que consideraremos um pouco mais tarde.
Deve ser lembrado que a maioria dos DBMSs não reconhece sua consulta do formulário:
SELECIONE Ostatki.Count distinto, Oboi distinto. * DE Oboi INNER JOIN Ostatki NO Oboi.id = Ostatki.id_oboi |
O argumento em questão foi especificado várias vezes aqui, ou foi especificado uma vez, mas antes da segunda, terceira ou outra coluna selecionável. Você receberá um erro citando uma imprecisão na sintaxe.
É óbvio que com uma construção competente da estruturatabelas e seu preenchimento, dentro de uma tabela, as situações são excluídas quando linhas absolutamente idênticas são encontradas. Portanto, a execução da consulta "Selecionar distinto *" com uma seleção de uma tabela é praticamente impraticável.
Imagine uma situação em que precisamos descobrir que tipo de papel de parede temos, para conveniência, iremos imediatamente classificar por tipo:
SELECIONE Oboi.type DE Oboi ordem por tipo |
E obtemos o resultado:
tipo |
Papel |
Papel |
Duas camadas de papel |
Duas camadas de papel |
Vinil |
Vinil |
Tecido |
Não tecido |
Não tecido |
Como você pode ver, existem linhas duplicadas na tabela. Se adicionarmos à cláusula Selecionar distinto:
SELECIONE Oboi.type distinto DE Oboi ordem por tipo |
obtemos o resultado sem repetições:
tipo |
Papel |
Duas camadas de papel |
Vinil |
Tecido |
Não tecido |
Assim, se os dados foram inseridos corretamentemesas, imediatamente após uma chamada ou solicitação do cliente, seremos capazes de responder que os papéis de parede líquido, de vidro e acrílico não estão disponíveis na loja. Considerando que o sortimento nas lojas geralmente não se limita a cem papéis de parede, seria muito trabalhoso examinar a lista de tipos não exclusivos.
O argumento distinto de SQL pode ser usado com qualquerfunção agregada. Mas para Min e Max, não terá efeito, e ao calcular a soma ou média, raramente se pode imaginar uma situação em que não seria necessário levar em conta as repetições.
Digamos que queremos saber o quão cheio está o nosso armazém e, para isso, enviamos um pedido que calcula o número total de rolos no armazém:
SELECT soma (Ostatki.count) DE Ostatki |
A solicitação retornará a resposta 143. Se mudarmos para:
SELECT soma (Ostatki.count distinto) DE Ostatki |
obtemos apenas 119, porque os papéis de parede dos artigos 3 e 7 estão no depósito na mesma quantidade. No entanto, essa resposta claramente não está correta.
Geralmente usado em SQL distinto com a função Count. Assim, sem dificuldade, podemos descobrir quantos tipos exclusivos de papel de parede geralmente temos:
SELECT contagem (distinto Oboi.type) DE Oboi |
E obter o resultado 5 - papel normal eduas camadas, vinil, tecido e não tecido. Com certeza todos já viram um anúncio do tipo: “Só temos mais de 20 tipos de papéis de parede diferentes!”, O que significa que nesta loja não há uma dúzia de rolos de tudo, mas papéis de parede dos mais diversos tipos modernos.
É interessante que em uma solicitação você possa especificarmúltiplas funções de contagem com e sem distintas. Ou seja, esta é a única situação em que distinto em Select pode aparecer várias vezes.
O argumento distinto de SQL deve ser descartado em um dos dois casos:
Digamos que seu chefe peça que você liste o papel de parede que você tem com apenas duas colunas - tipo e cor. Por hábito, você fornece o argumento distinto:
SELECIONE Oboi.type distinto, Oboi.color DE Oboi ORDEM POR Oboi.tipo |
E - você perde alguns dos dados:
tipo | cor |
Papel | Multicolorido |
Duas camadas de papel | Bege |
Vinil | Castanho |
Vinil | laranja |
Tecido | Rosa |
Não tecido | Bege |
Não tecido | Brancos |
Pode parecer que temos apenas um tipo de papel de parede (comum e de duas camadas), embora de fato, mesmo em nossa mesinha haja dois artigos cada (o resultado é indistinto):
tipo | cor |
Papel | Multicolorido |
Papel | Multicolorido |
Duas camadas de papel | Bege |
Duas camadas de papel | Bege |
Vinil | Castanho |
Vinil | laranja |
Tecido | Rosa |
Não tecido | Brancos |
Não tecido | Bege |
Portanto, como ao escrever qualquer consulta, com o argumento distinto, você deve ter cuidado e resolver o problema com competência com sua aplicação, dependendo da tarefa em mãos.
O oposto de distinto é um argumentoTudo. Linhas duplicadas são preservadas quando aplicadas. Mas, como por padrão o DBMS pensa que todos os valores devem ser exibidos, o argumento All é mais um qualificador do que um argumento funcional real.