Database
 sql >> Base de Dados >  >> RDS >> Database

Cláusula SQL UNION para iniciantes


Em SQL, o UNION A cláusula concatena os resultados de duas consultas em um único conjunto de resultados.

Você pode usar o UNION cláusula com ou sem ALL argumento:
  • UNION ALL – Inclui duplicatas.
  • UNION – Exclui duplicatas.

Abaixo estão alguns exemplos básicos para demonstrar como funciona.

Tabelas de amostra


Suponha que temos duas tabelas:Cats e Dogs

Cats
+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Meow      |
| 2       | Fluffy    |
| 3       | Scratch   |
+---------+-----------+

Dogs
+---------+-----------+
| DogId   | DogName   |
|---------+-----------|
| 1       | Fetch     |
| 2       | Fluffy    |
| 3       | Wag       |
| 1002    | Fetch     |
+---------+-----------+

Podemos usar um SELECT declaração com um UNION cláusula para combinar os resultados de ambas as tabelas em um conjunto de resultados.

Exemplo usando UNION ALL


Primeiro, vamos usar UNION ALL para que inclua duplicatas.
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;

Resultado:
+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fetch     |
| Meow      |
| Fluffy    |
| Scratch   |
+-----------+
(7 rows affected)

Nesse caso, sete linhas são retornadas. Podemos ver que “Fetch” é retornado duas vezes. Isso ocorre porque existem dois cães chamados Fetch.

Há também um gato e um cachorro com o mesmo nome:Fofo.

Observe que usei um alias de coluna para nomear o campo retornado pela operação. Se eu não tivesse feito isso, o resultado teria usado os nomes das colunas da primeira consulta. Nesse caso, o cabeçalho da coluna teria sido chamado de DogName em vez de PetName .
SELECT DogName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;

Resultado:
+-----------+
| DogName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fetch     |
| Meow      |
| Fluffy    |
| Scratch   |
+-----------+
(7 rows affected)

Isso pode ou não ser aceitável, dependendo dos dados que você está retornando em sua consulta. No nosso caso, não é apropriado, porque nem todos os resultados são cães.

Exemplo usando UNION


Vamos ver o que acontece quando removemos o ALL argumento.
SELECT DogName AS PetName
FROM Dogs
UNION
SELECT CatName
FROM Cats;

Resultado:
+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Meow      |
| Scratch   |
| Wag       |
+-----------+
(5 rows affected)

Desta vez, apenas cinco linhas são retornadas. Ambas as duplicatas são removidas.

UNION vs DISTINCT


Observe que isso é diferente de aplicar DISTINCT para cada SELECT individual demonstração. Se tivéssemos feito isso, Fluffy teria sido retornado duas vezes, porque o ALL só se aplicaria ao SELECT declaração que está sendo aplicada (não aos resultados concatenados).

Aqui está um exemplo para ilustrar o que quero dizer.
SELECT DISTINCT DogName AS PetName
FROM Dogs
UNION ALL
SELECT DISTINCT CatName
FROM Cats;

Resultado:
+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fluffy    |
| Meow      |
| Scratch   |
+-----------+
(6 rows affected)

Todas as consultas devem retornar o mesmo número de colunas


Quando você usa o UNION cláusula, cada consulta deve ter o mesmo número de colunas e elas devem estar na mesma ordem.

Se não, você receberá um erro.
SELECT CatName FROM Cats
UNION ALL
SELECT DogId, DogName FROM Dogs;

Resultado:
Msg 205, Level 16, State 1, Line 1
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.

Esse é o erro que o SQL Server retorna ao usar um número desigual de colunas. Este erro específico indica que a mesma restrição também se aplica ao INTERSECT e EXCEPT operadores. A mensagem de erro que você recebe pode ser diferente, dependendo do seu DBMS.

Os tipos de dados devem ser compatíveis


Além de exigir o mesmo número de colunas, essas colunas devem ter um tipo de dados compatível.

Eles não precisam necessariamente ser do mesmo tipo de dados, mas precisarão ser compatíveis. Ou seja, eles devem ser compatíveis por meio de conversão implícita. Se os tipos de dados não corresponderem, o DBMS deve ser capaz de fazer uma conversão implícita para que eles correspondam.

Se não, você receberá um erro.
SELECT CatName FROM Cats
UNION ALL
SELECT DogId FROM Dogs;

Resultado:
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'Meow' to data type int.

Ordenando os resultados


Se você deseja classificar os resultados com o ORDER BY cláusula, você precisará colocá-la na última consulta. Você não pode colocar um ORDER BY separado cláusula em cada consulta ou, nesse caso, qualquer consulta que não seja a última.

Aqui está o erro que recebo ao tentar fazer isso no SQL Server:
SELECT DogName AS PetName
FROM Dogs
ORDER BY DogName
UNION ALL
SELECT CatName
FROM Cats;

Resultado:
Msg 156, Level 15, State 1, Line 4
Incorrect syntax near the keyword 'UNION'.

Portanto, se quisermos ordenar os resultados, precisaremos fazer algo assim:
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
ORDER BY PetName;

Aplicando UNION para Mais de duas consultas


Os exemplos anteriores combinaram resultados de duas consultas diferentes, mas não há nada que impeça você de adicionar mais. Você pode usá-lo para combinar os resultados de muitas consultas, se necessário.

Por exemplo, se também tivéssemos um Birds tabela, poderíamos fazer isso:
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
UNION ALL
SELECT BirdName
FROM Birds;

Normalização


Os exemplos nesta página colocam gatos e cachorros em duas tabelas separadas. A razão de eu ter feito isso é porque é uma maneira clara e concisa de ilustrar como UNION funciona.

Na prática, você pode tê-los na mesma tabela chamada, digamos Pets , então tenha um PetTypes separado mesa (ou similar). Isso é conhecido como normalização e é a maneira como os bancos de dados relacionais são geralmente projetados.

Você pode então executar uma junção nessas tabelas para retornar dados conforme necessário.