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.