UNION e UNION ALL empilham verticalmente os resultados de dois ou mais SELECT: as linhas de uma consulta sao anexadas abaixo das de outra. A diferenca e uma unica palavra-chave, mas e ela que define tanto a correcao quanto o desempenho.
UNION versus UNION ALL
UNION ALL simplesmente concatena os conjuntos de linhas e nao verifica nada quanto a repeticoes. UNION ainda remove duplicatas e, para encontra-las, o motor precisa ordenar ou aplicar hash em todo o resultado.
SELECT country FROM users
UNION ALL
SELECT country FROM users;
SELECT country FROM users
UNION
SELECT country FROM users;
Regra pratica: se voce ja sabe que as entradas nao se sobrepoem (por exemplo, ao empilhar pedidos de meses diferentes), use UNION ALL. A deduplicacao extra sobre milhoes de linhas custa segundos reais de CPU e memoria para a ordenacao.
UNION ALL — sem deduplicacao, a ordem das linhas nao e garantida, mas costuma ser mais barato.
UNION — deduplica sobre todo o conjunto de colunas, nao apenas a primeira.
- Uma duplicata e uma linha que coincide por inteiro; aqui
NULL e igual a NULL (ao contrario da comparacao normal).
Regras de compatibilidade de colunas
So da para combinar consultas com o mesmo numero de colunas e tipos compativeis. Os nomes das colunas vem do primeiro SELECT; os demais sao ignorados.
SELECT id, email FROM users
UNION ALL
SELECT user_id, status FROM orders;
SELECT id, email FROM users
UNION ALL
SELECT id, user_id, amount FROM orders;
Se os tipos diferem, alinhe-os de forma explicita com CAST em vez de confiar na conversao implicita. Para que uma pilha heterogenea faca sentido, adicione uma coluna de origem:
SELECT id, name, CAST(NULL AS numeric) AS amount, 'user' AS source
FROM users
UNION ALL
SELECT id, CAST(NULL AS text), amount, 'order'
FROM orders;
ORDER BY e LIMIT sobre a uniao
ORDER BY se aplica a todo o resultado e e escrito uma unica vez, bem no fim. Ordenar ramos individuais nao adianta: o UNION pode reorganizar as linhas de qualquer forma.
SELECT id, name, salary FROM employees WHERE dept = 'eng'
UNION ALL
SELECT id, name, salary FROM employees WHERE dept = 'sales'
ORDER BY salary DESC
LIMIT 10;
Se precisar ordenar ou limitar um ramo especifico, envolva-o em parenteses e uma subconsulta:
SELECT * FROM (
SELECT id, amount FROM orders WHERE status = 'paid'
ORDER BY amount DESC LIMIT 5
) AS top_paid
UNION ALL
SELECT id, amount FROM orders WHERE status = 'refunded';
Pegadinha: o ORDER BY final ordena por posicao da coluna ou pelo nome do primeiro SELECT. Se os ramos nomeiam as colunas de forma diferente, use o nome do primeiro ramo ou o numero da posicao (ORDER BY 3).
Diferencas entre motores
- PostgreSQL — verificacao estrita de tipos;
UNION usa um Sort ou Hash Aggregate, visivel no EXPLAIN.
- MySQL — permite mais conversoes implicitas e as vezes trunca valores em silencio; coloque o
ORDER BY/LIMIT de um ramo em uma subconsulta ou ele sera ignorado.
- ClickHouse — por padrao o
UNION sem ALL pode exigir configuracao explicita; aqui quase sempre se escreve UNION ALL e a deduplicacao e feita com DISTINCT ou agregados.
Resumindo: UNION ALL e a escolha padrao pela velocidade, e voce recorre ao UNION de forma deliberada, so quando as repeticoes realmente precisam ser colapsadas.
UNIONeUNION ALLempilham verticalmente os resultados de dois ou maisSELECT: as linhas de uma consulta sao anexadas abaixo das de outra. A diferenca e uma unica palavra-chave, mas e ela que define tanto a correcao quanto o desempenho.UNION versus UNION ALL
UNION ALLsimplesmente concatena os conjuntos de linhas e nao verifica nada quanto a repeticoes.UNIONainda remove duplicatas e, para encontra-las, o motor precisa ordenar ou aplicar hash em todo o resultado.-- Keeps every row, including duplicates. Fast. SELECT country FROM users UNION ALL SELECT country FROM users; -- Collapses identical rows into one. Extra dedup pass. SELECT country FROM users UNION SELECT country FROM users;Regra pratica: se voce ja sabe que as entradas nao se sobrepoem (por exemplo, ao empilhar pedidos de meses diferentes), use
UNION ALL. A deduplicacao extra sobre milhoes de linhas custa segundos reais de CPU e memoria para a ordenacao.UNION ALL— sem deduplicacao, a ordem das linhas nao e garantida, mas costuma ser mais barato.UNION— deduplica sobre todo o conjunto de colunas, nao apenas a primeira.NULLe igual aNULL(ao contrario da comparacao normal).Regras de compatibilidade de colunas
So da para combinar consultas com o mesmo numero de colunas e tipos compativeis. Os nomes das colunas vem do primeiro
SELECT; os demais sao ignorados.-- OK: same arity, compatible types SELECT id, email FROM users UNION ALL SELECT user_id, status FROM orders; -- Fails: 2 columns vs 3 columns SELECT id, email FROM users UNION ALL SELECT id, user_id, amount FROM orders;Se os tipos diferem, alinhe-os de forma explicita com
CASTem vez de confiar na conversao implicita. Para que uma pilha heterogenea faca sentido, adicione uma coluna de origem:SELECT id, name, CAST(NULL AS numeric) AS amount, 'user' AS source FROM users UNION ALL SELECT id, CAST(NULL AS text), amount, 'order' FROM orders;ORDER BY e LIMIT sobre a uniao
ORDER BYse aplica a todo o resultado e e escrito uma unica vez, bem no fim. Ordenar ramos individuais nao adianta: oUNIONpode reorganizar as linhas de qualquer forma.SELECT id, name, salary FROM employees WHERE dept = 'eng' UNION ALL SELECT id, name, salary FROM employees WHERE dept = 'sales' ORDER BY salary DESC LIMIT 10;Se precisar ordenar ou limitar um ramo especifico, envolva-o em parenteses e uma subconsulta:
SELECT * FROM ( SELECT id, amount FROM orders WHERE status = 'paid' ORDER BY amount DESC LIMIT 5 ) AS top_paid UNION ALL SELECT id, amount FROM orders WHERE status = 'refunded';Diferencas entre motores
UNIONusa um Sort ou Hash Aggregate, visivel noEXPLAIN.ORDER BY/LIMITde um ramo em uma subconsulta ou ele sera ignorado.UNIONsemALLpode exigir configuracao explicita; aqui quase sempre se escreveUNION ALLe a deduplicacao e feita comDISTINCTou agregados.Resumindo:
UNION ALLe a escolha padrao pela velocidade, e voce recorre aoUNIONde forma deliberada, so quando as repeticoes realmente precisam ser colapsadas.