Operadores de conjunto

Os SET OPERATORS ou operadores de conjunto são cláusulas SQL que servem para realizar operações, existem quatro operadores definidos: UNION, UNION ALL, INTERSECT e MINUS. Os operadores de conjunto combinam duas ou mais instruções SELECT separadas para que sua saída seja mesclada de alguma maneira.

INTERSECT

O INTERSECT retorna linhas que são idênticas nas duas consultas, exemplo:

SELECT * FROM Y
INTERSECT
SELECT * FROM X;

Resultado: NO DATA FOUND

Na consulta acima a tabela acima retorna uma coluna com 3 linhas (1,2,3) e a consulta X retorna uma linha (4), dessa forma o resultado não traz nenhuma linha pois não há linhas com valores idênticos (1,2,3) e (4).

SELECT * FROM Y
INTERSECT
SELECT * FROM X;

Resultado: 3 (OBS: Não repete)

Na consulta acima a tabela Y acima retorna uma coluna com 3 linhas (1,2,3) e a consulta X retorna duas linhas (3,4), dessa forma o resultado traz uma linha com o valor (3), pois o número 3 é uma linha que se encontra tanto na tabela Y como na tabela X.

INTERSECT eliminará linhas duplicadas e ordenará o resultado da esquerda para a direita. Se um ou ambos os conjuntos de linhas da instrução SELECT contiverem duplicadas em seu próprio conjunto de linhas, a saída resultante do INTERSECT eliminará essas duplicadas.

MINUS

O MINUS começará com a primeira instrução SELECT e removerá todas as linhas da saída desse SELECT que possam aparecer na segunda saída do SELECT. Os resultados podem diferir, dependendo de qual SELECT é colocado primeiro e qual é o segundo. Vejamos um exemplo:

select id from x
MINUS
select id from y;

Resultado: 2

A consulta acima a tabela X retorna uma coluna ID com duas linhas com os valores (1,2) ou seja na linha um retorna o valor numérico 1 e na linha dois retornada possui o valor numérico 2. Na tabela Y temos duas linhas de retorno da coluna ID sendo (1,3). Executando o MINUS entre as duas consultas temos como retorno o valor 2. O MINUS sempre irá retornar dados da primeira consulta SELECT removendo o valor que encontra no segundo select, nesse caso o valor idêntico é o número 1, então tínhamos (1,2) removendo o 1 só sobrou o valor numérico 2.

Vejamos o exemplo 2:

select id from x
MINUS
select id from y;

Resultado: no data found

A consulta acima a tabela X retorna duas linhas (1,2) e a tabela Y retorna três linhas (1,2,3), veja que os valores (1,2) da tabela X se encontra os mesmos valores da tabela Y que também tem (1,2 e também tem o 3), sendo assim descontando os valores idênticos o resultado é NO DATA FOUND, ou seja, nenhum dado de retorno.

Veremos o exemplo 3:

SELECT * FROM Y
MINUS
SELECT * FROM X;
Resultado: 3

A consulta acima a tabela Y retorna três linhas com os seguintes valores (1,2,3) e a tabela X retorna duas linhas (1,2), removendo os valores idênticos o que sobra da tabela Y é o valor numérico 3.

Exemplo 4:

SELECT * FROM Y
MINUS
SELECT * FROM X;

Resultado: 1,2,3

A consulta acima a tabela Y retorna três linhas com os seguintes valores (1,2,3) e a tabela X retorna uma linha com o valor numérico (4), observe que não há valores idênticos entre a tabela Y e X dessa forma todas linhas da tabela Y retornam como resultado.

UNION e UNION ALL

O UNION une as linhas das duas consultas e elimina registros duplicados e ordena as colunas da esquerda pra direita, ou seja faz um ORDER BY caso não haja ele faz automático.

A diferença do UNION ALL é que não remove registros duplicados nem faz ORDER BY automático.

Vejamos um exemplo de cada e seu respectivo resultado:

Exemplo de UNION:

select * from(
select 1 from dual
union all
select 2 from dual
union all
select 2 from dual
union all
select 3 from dual
union all
select 0 from dual
)
UNION
select * from(
select 1 from dual
)
Resultado: 0, 1, 2, 3
Foi eliminado registros duplicados e retornou em ordem crescente.

Exemplo de UNION ALL:

select * from(
select 1 from dual
union all
select 2 from dual
union all
select 2 from dual
union all
select 3 from dual
union all
select 0 from dual
)
UNION ALL
select * from(
select 1 from dual
)
Resultado: 1, 2, 2, 3, 0, 1
Juntou todas as linhas, não removeu registros duplicados e nem ordenou os dados.

Combinações

Os operadores de conjunto podem ser usados em várias combinações, como por exemplo:

SELECT...
UNION
SELECT...
INTERSECT
SELECT...
MINUS
SELECT...

A ordem de execução dessa instrução é sequencial, ou seja, primeiro executa o SELECT UNION SELECT depois o resultado dessa operação com INTERSECT SELECT depois o resultado dessa operação com MINUS SELECT e assim encerra a operação.

Tais combinações podem ser continuadas indefinidamente. Os operadores de conjunto têm precedência igual entre si, o que significa que todos serão executados do início ao fim na ordem em que aparecem na instrução SELECT. Para alterar a ordem de execução, use parênteses, assim:

Caso haja parêntesis, então as instruções entre parêntesis serão executados em ordem prioritária. Também devemos observar o seguinte:

SELECT...
UNION
(SELECT...
INTERSECT
SELECT...)
MINUS
SELECT...

Caso deseje um ORDER BY pode colocar na instrução entre parêntesis, mas só pode colocar no último SELECT, exemplo:

select * from(
select 3 from dual
union all
select 0 from dual
order by 1
)
UNION ALL
select * from(
select 1 from dual
) order by 1 desc

Note que foi usado dois ORDER BY, a consulta executa com sucesso, no entanto note que o ORDER BY tanto da consulta entre parêntesis como a consulta exterior ele está na última posição, caso colocasse o order by em outra posição que não a última daria erro, exemplo:

select * from(
select 3 from dual order by 1
union all
select 0 from dual)
UNION ALL
select * from(
select 1 from dual
) order by 1 desc

A consulta acima dá erro pois o ORDER BY na linha dois está na primeira consulta, pra funcionar deveria estar na consulta da linha 4.

Referência

OCA Oracle Database SQL Exam 1Z0-071. Páginas 565 – 578.