No MySQL, o
UNION
cláusula combina os resultados de várias consultas em um único conjunto de resultados. Exemplo
Suponha que temos as seguintes tabelas:
SELECT * FROM Teachers;
SELECT * FROM Students;
Resultado:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 1 | Warren | | 2 | Ben | | 3 | Cathy | | 4 | Cathy | | 5 | Bill | | 6 | Bill | +-----------+-------------+ +-----------+-------------+ | StudentId | StudentName | +-----------+-------------+ | 1 | Faye | | 2 | Jet | | 3 | Spike | | 4 | Ein | | 5 | Warren | | 6 | Bill | +-----------+-------------+
Podemos inserir o
UNION
cláusula entre esses dois SELECT
declarações para devolver a todos os professores e alunos:SELECT TeacherName FROM Teachers
UNION
SELECT StudentName FROM Students;
Resultado:
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Bill | | Faye | | Jet | | Spike | | Ein | +-------------+
Os nomes das colunas são retirados do primeiro
SELECT
demonstração. Por padrão, o
UNION
cláusula aplica implicitamente um DISTINCT
Operação. Em outras palavras, ele retorna apenas valores distintos por padrão. Portanto, os resultados acima contêm apenas um de Warren, Cathy e Bill. Isso apesar do fato de que as tabelas combinadas na verdade contêm dois Warrens, dois Cathys e três Bills (há dois professores chamados Cathy, um professor e um cliente chamados Warren, e dois chamados Bill, bem como um aluno chamado Bill). Aqui está um exemplo que usa explicitamente o
DISTINCT
cláusula:SELECT TeacherName FROM Teachers
UNION DISTINCT
SELECT StudentName FROM Students;
Resultado:
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Bill | | Faye | | Jet | | Spike | | Ein | +-------------+
Assim, obtemos o mesmo resultado que obtivemos sem o
DISTINCT
cláusula. Incluir duplicatas
Podemos usar o
ALL
palavra-chave para incluir valores duplicados nos resultados:SELECT TeacherName FROM Teachers
UNION ALL
SELECT StudentName FROM Students;
Resultado:
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Cathy | | Bill | | Bill | | Faye | | Jet | | Spike | | Ein | | Warren | | Bill | +-------------+
Desta vez, obtivemos doze linhas em vez das oito que obtivemos em nosso primeiro exemplo.
Podemos ver que ambas as Cathys foram devolvidas e todos os três Bills foram devolvidos.
TABLE
Declarações
A partir do MySQL 8.0.19 podemos usar o
UNION
cláusula com a TABLE
demonstração. Aqui está um exemplo:
TABLE Teachers
UNION
TABLE Students;
Resultado:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 1 | Warren | | 2 | Ben | | 3 | Cathy | | 4 | Cathy | | 5 | Bill | | 6 | Bill | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 4 | Ein | | 5 | Warren | +-----------+-------------+
Isso é o equivalente da seguinte consulta:
SELECT * FROM Teachers
UNION
SELECT * FROM Students;
Resultado:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 1 | Warren | | 2 | Ben | | 3 | Cathy | | 4 | Cathy | | 5 | Bill | | 6 | Bill | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 4 | Ein | | 5 | Warren | +-----------+-------------+
Você notará que essas instruções retornam mais linhas do que em nosso primeiro exemplo anterior. Isso ocorre porque estamos selecionando todas as colunas na tabela, o que resulta em não duplicatas onde anteriormente havia uma duplicata. Por exemplo, dois professores chamados Bill são retornados aqui, enquanto apenas um foi retornado no exemplo anterior. Isso porque o
TeacherId
as colunas contêm valores diferentes, portanto, as linhas não são duplicadas. Usando o ORDER BY
Cláusula em consultas de união
Podemos usar o
ORDER BY
cláusula em cada SELECT
declaração e/ou no combinado UNION
inquerir. Em cada SELECT
Declaração
Quando usamos o
ORDER BY
cláusula no SELECT
individual declarações dentro de um UNION
consulta, precisamos incluir cada SELECT
declaração entre parênteses:(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2);
Resultado:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 2 | Ben | | 5 | Bill | | 6 | Bill | | 4 | Ein | +-----------+-------------+
Observe que, quando fazemos isso, ele não ordena os resultados para a saída. Ele só ordena os resultados com a finalidade de determinar o subconjunto das linhas selecionadas a serem recuperadas ao aplicar o
LIMIT
cláusula. Portanto, usando
ORDER BY
sem o LIMIT
cláusula não tem efeito na saída. Em todo o UNION
Consulta
Também podemos usar um
ORDER BY
cláusula em toda a consulta, para que toda a saída seja ordenada em conjunto. Neste exemplo, pegamos o exemplo anterior e ordenamos os resultados combinados:
(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2)
ORDER BY TeacherName DESC;
Resultado:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 4 | Ein | | 5 | Bill | | 6 | Bill | | 2 | Ben | +-----------+-------------+
Mesmo quando não estiver usando o
ORDER BY
cláusula dentro de cada SELECT
instrução, cada SELECT
A instrução ainda deve estar entre parênteses, e o ORDER BY
cláusula (ou qualquer LIMIT
cláusula) deve ser após o último. (SELECT * FROM Teachers)
UNION
(SELECT * FROM Students)
ORDER BY TeacherName ASC;
Resultado:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 2 | Ben | | 5 | Bill | | 6 | Bill | | 3 | Cathy | | 4 | Cathy | | 4 | Ein | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 1 | Warren | | 5 | Warren | +-----------+-------------+
Lembre-se, omitir os parênteses produz o mesmo resultado que aquele com parênteses:
SELECT * FROM Teachers
UNION
SELECT * FROM Students
ORDER BY TeacherName ASC;
Resultado:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 2 | Ben | | 5 | Bill | | 6 | Bill | | 3 | Cathy | | 4 | Cathy | | 4 | Ein | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 1 | Warren | | 5 | Warren | +-----------+-------------+
Observe que, se uma coluna a ser classificada usar um alias, essa coluna deverá ser referenciada por seu alias (não pelo nome da coluna).
Exemplo:
(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY t ASC;
Resultado:
+--------+ | t | +--------+ | Ben | | Bill | | Cathy | | Ein | | Faye | | Jet | | Spike | | Warren | +--------+
Veja o que acontece se não usarmos o alias:
(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY TeacherName ASC;
Resultado:
ERROR 1054 (42S22): Unknown column 'TeacherName' in 'order clause'
Número de colunas
O número de colunas retornadas por cada
SELECT
declaração deve ser a mesma. Portanto, não podemos fazer o seguinte:SELECT TeacherName FROM Teachers
UNION
SELECT StudentId, StudentName FROM Students;
Resultado:
ERROR 1222 (21000): The used SELECT statements have a different number of columns
Tipos de dados
Colunas selecionadas listadas nas posições correspondentes de cada
SELECT
instrução deve ter o mesmo tipo de dados. No entanto, se não, os tipos e comprimentos das colunas no UNION
resultado leva em conta os valores recuperados por todos os SELECT
declarações. Veja o que acontece se tentarmos combinar o
TeacherName
coluna com o StudentId
coluna:SELECT TeacherName FROM Teachers
UNION
SELECT StudentId FROM Students;
Resultado:
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Bill | | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | +-------------+
Alguns outros RDBMSs produziriam um erro nesta instância, mas o MySQL consegue produzir uma saída sem erros.