7.4. Combinação de consultas

Pode-se combinar os resultados de duas consultas utilizando as operações de conjunto união, interseção e diferença [1] [2] [3] [4] . A sintaxe é

consulta1 UNION [ALL] consulta2
consulta1 INTERSECT [ALL] consulta2
consulta1 EXCEPT [ALL] consulta2

onde consulta1 e consulta2 são consultas que podem utilizar qualquer uma das funcionalidades mostradas até aqui. As operações de conjuntos também podem ser aninhadas ou encadeadas. Por exemplo:

consulta1 UNION consulta2 UNION consulta3

significa, na verdade,

(consulta1 UNION consulta2) UNION consulta3

Efetivamente, UNION anexa o resultado da consulta2 ao resultado da consulta1 (embora não haja garantia que esta seja a ordem que as linhas realmente retornam). Além disso, são eliminadas do resultado as linhas duplicadas, do mesmo modo que no DISTINCT, a não ser que seja utilizado UNION ALL.

INTERSECT retorna todas as linhas presentes tanto no resultado da consulta1 quanto no resultado da consulta2. As linhas duplicadas são eliminadas, a não ser que seja utilizado INTERSECT ALL.

EXCEPT retorna todas as linhas presentes no resultado da consulta1, mas que não estão presentes no resultado da consulta2 (às vezes isto é chamado de diferença entre duas consultas). Novamente, as linhas duplicadas são eliminadas a não ser que seja utilizado EXCEPT ALL.

Para ser possível calcular a união, a interseção, ou a diferença entre duas consultas, as duas consultas devem ser "compatíveis para união", significando que ambas devem retornar o mesmo número de colunas, e que as colunas correspondentes devem possuir tipos de dado compatíveis, conforme descrito na Seção 10.5 .

Nota: O exemplo abaixo foi escrito pelo tradutor, não fazendo parte do manual original.

Exemplo 7-5. Linhas diferentes em duas tabelas com definições idênticas

Este exemplo mostra a utilização de EXCEPT e UNION para descobrir as linhas diferentes de duas tabelas semelhantes.

CREATE TEMPORARY TABLE a (c1 text, c2 text, c3 text);
INSERT INTO a VALUES ('x', 'x', 'x');
INSERT INTO a VALUES ('x', 'x', 'y'); -- nas duas tabelas
INSERT INTO a VALUES ('x', 'y', 'x');

CREATE TEMPORARY TABLE b (c1 text, c2 text, c3 text);
INSERT INTO b VALUES ('x', 'x', 'y'); -- nas duas tabelas
INSERT INTO b VALUES ('x', 'x', 'y'); -- nas duas tabelas
INSERT INTO b VALUES ('x', 'y', 'y');
INSERT INTO b VALUES ('y', 'y', 'y');
INSERT INTO b VALUES ('y', 'y', 'y');

-- No comando abaixo só um par ('x', 'x', 'y') é removido do resultado
-- Este comando executa no DB2 8.1 sem alterações.

(SELECT 'a-b' AS dif, a.* FROM a EXCEPT ALL SELECT 'a-b', b.* FROM b)
UNION ALL
(SELECT 'b-a', b.* FROM b EXCEPT ALL SELECT 'b-a', a.* FROM a);

 dif | c1 | c2 | c3
-----+----+----+----
 a-b | x  | x  | x
 a-b | x  | y  | x
 b-a | x  | x  | y
 b-a | x  | y  | y
 b-a | y  | y  | y
 b-a | y  | y  | y
(6 linhas)

-- No comando abaixo são removidas todas as linhas ('x', 'x', 'y'),
-- e só é mostrada uma linha ('y', 'y', 'y') no resultado.
-- Este comando executa no DB2 8.1 sem alterações.
-- Este comando executa no Oracle 10g trocando EXCEPT por MINUS.

(SELECT 'a-b' AS dif, a.* FROM a EXCEPT SELECT 'a-b', b.* FROM b)
UNION
(SELECT 'b-a', b.* FROM b EXCEPT SELECT 'b-a', a.* FROM a);

 dif | c1 | c2 | c3
-----+----+----+----
 a-b | x  | x  | x
 a-b | x  | y  | x
 b-a | x  | y  | y
 b-a | y  | y  | y
(4 linhas)

Notas

[1]

Dados dois conjuntos A e B: chama-se diferença entre A e B o conjunto formado pelos elementos de A que não pertencem a B; chama-se interseção de A com B o conjunto formado pelos elementos comuns ao conjunto A e ao conjunto B; chama-se união de A com B o conjunto formado pelos elementos que pertencem a A ou B. Edwaldo Bianchini e Herval Paccola - Matemática - Operações com conjuntos. (N. do T.)

[2]

SQL Server 2000 — possui o operador UNION [ALL], mas não possui os operadores INTERSECT e EXCEPT, embora estas duas sejam palavras reservadas. (N. do T.)

[3]

Oracle 9i — possui os operadores UNION [ALL], INTERSECT e MINUS (equivalente ao EXCEPT). Set Operators . (N. do T.)

[4]

DB2 8.1 — possui os operadores UNION [ALL], INTERSECT [ALL] e EXCEPT [ALL]. (N. do T.)

SourceForge.net Logo