O operador union combina, em apenas um, os resultados(result set) de dois ou mais select. O operador union usa os nomes das colunas do primeiro select como os nomes das colunas do resultado final.
Veja: Termos: O que é RESULT SET em Banco de Dados?
As instruções SELECT precisam ter o mesmo número de colunas. Além disso, as colunas correspondentes do primeiro select devem ter o mesmo tipo de dados que as colunas do segundo select.
Opções ALL e DISTINCT do Operador UNION
distinct instrui o operador union a remover linhas duplicadas enquanto a opção all exibirá tudo.
distinct e all são de uso opcional. Por padrão, union usa a opção distinct se você não especificar nada.
Na imgem a seguir podemos ver que o resultado(result set) não tem duplicidade:
Aqui é usado all e a duplicidade de dados existe
Se atente para isso: Os select podem usar order by. No entanto, order by dos selects não mudarão nada na ordem das linhas do resultado final.
Tabelas que Usaremos nos Exemplos
Usaremos as tabelas guests e vips do banco de dados nation que baixamos pronta no artigo: Baixando Exemplo de Banco de Dados.
As duas tabelas têm esse conteúdo:
Tabela guests
MariaDB [nation]> select * from guests; +----------+--------+ | guest_id | name | +----------+--------+ | 1 | John | | 2 | Jane | | 3 | Jean | | 4 | Storm | | 5 | Beast | | 6 | | | 7 | silvia | | 8 | maria | +----------+--------+
Tabela vips
MariaDB [nation]> select * from vips; +--------+-----------+ | vip_id | name | +--------+-----------+ | 1 | Jane | | 2 | Charles | | 3 | John | | 4 | Wolverine | | 5 | Rogue | | 6 | | | 7 | maria | | 8 | silvia | +--------+-----------+
Exemplos usando Operador UNION
#1 Unindo as tabelas com union
select vip_id, name from vips union select guest_id, name from guests;
MariaDB [nation]> select vip_id, name from vips union select guest_id, name from guests; +--------+-----------+ | vip_id | name | +--------+-----------+ | 1 | Jane | | 2 | Charles | | 3 | John | | 4 | Wolverine | | 5 | Rogue | | 6 | | | 7 | maria | | 8 | silvia | | 1 | John | | 2 | Jane | | 3 | Jean | | 4 | Storm | | 5 | Beast | | 7 | silvia | | 8 | maria | +--------+-----------+
#2 Podemos fazer com que apareça uma a palavra “vip” na frente de tudo que for da tabela vips e “convidado” na frente de todos os registros da tabela guests
select vip_id, name, ‘vip’ as tipo from vips union distinct select guest_id,
name, ‘convidado’ from guests;
MariaDB [nation]> select vip_id, name, 'vip' as tipo from vips union distinct select guest_id, name, 'convidado' from guests; +--------+-----------+-----------+ | vip_id | name | tipo | +--------+-----------+-----------+ | 1 | Jane | vip | | 2 | Charles | vip | | 3 | John | vip | | 4 | Wolverine | vip | | 5 | Rogue | vip | | 6 | | vip | | 7 | maria | vip | | 8 | silvia | vip | | 1 | John | convidado | | 2 | Jane | convidado | | 3 | Jean | convidado | | 4 | Storm | convidado | | 5 | Beast | convidado | | 6 | | convidado | | 7 | silvia | convidado | | 8 | maria | convidado | +--------+-----------+-----------+
#3 agora usaremos union distinct
Tanto faz usar “union distinct” ou somente “union”
select name from guests union distinct select name from vips order by name;
MariaDB [nation]> select name from guests union distinct select name from vips order by name; +-----------+ | name | +-----------+ | | | Beast | | Charles | | Jane | | Jean | | John | | maria | | Rogue | | silvia | | Storm | | Wolverine | +-----------+
#4 usando union all
select name from guests union all select name from vips order by name;
MariaDB [nation]> select name from guests union all select name from vips order by name; +-----------+ | name | +-----------+ | | | | | Beast | | Charles | | Jane | | Jane | | Jean | | John | | John | | maria | | maria | | Rogue | | silvia | | silvia | | Storm | | Wolverine | +-----------+
Não Confunda UNION com JOIN
join combina colunas de duas ou mais tabelas enquanto uma union combina linhas dos result set(resultados) de duas ou mais instruções select.
Simplificando, join anexa resultados horizontalmente enquanto uma union anexa conjuntos de resultados verticalmente.