Consulta UNION UNION ALL

A consulta cria uma tabela virtual baseada em tabelas existentes ou constantes transformadas em tabelas.

Sintaxe { ( Consulta ) | Consulta INTERSECT [ ALL | DISTINCT ] Consulta | Consulta EXCEPT [ ALL | DISTINCT ] Consulta | Consulta UNION [ ALL | DISTINCT ] Consulta | ExpressãoSeleção | VALUES Expressão }

Pode-se colocar parênteses arbitrariamente em torno das consultas, ou utilizar parênteses para controlar a ordem de avaliação das operações INTERSECT, EXCEPT e UNION. Estas operações são avaliadas da esquerda para a direita quando não existem parênteses presentes, com exceção das operações INTERSECT, que são avaliadas antes das operações de UNION e EXCEPT.

Linhas duplicadas nos resultados de UNION, INTERSECT e EXCEPT ALL

As palavras chave ALL e DISTINCT determinam se as linhas duplicadas são eliminadas do resultado da operação. Se for especificada a palavra chave DISTINCT, então o resultado não terá linhas duplicadas. Se for especificada a palavra chave ALL, então poderão existir linhas duplicadas no resultado, dependendo da existência de linhas duplicadas na entrada. DISTINCT é o padrão, portanto se não for especificado nem ALL nem DISTINCT as linhas duplicadas serão eliminadas. Por exemplo, UNION constrói um ResultSet intermediário com todas as linhas das duas consultas, e elimina as linhas duplicadas antes de retornar as linhas remanescentes. UNION ALL retorna todas as linhas das duas consultas como resultado.

Dependendo da operação especificada, se o número de cópias de uma determinada linha na tabela à esquerda for L, e o número de cópias desta linha na tabela à direita for R, então o número de linhas duplicadas desta determinada linha contidas na tabela de saída será (assumindo que a palavra chave ALL foi especificada):

  • UNION: ( L + R ).
  • EXCEPT: o maior entre ( L – R ) e 0 (zero).
  • INTERSECT: o menor entre L e R.

Exemplos -- Uma expressão de seleção SELECT * FROM ORG; -- uma subconsulta SELECT * FROM (SELECT COD_CLASSE FROM CLASSE_AGENDA) AS CS; -- uma subconsulta SELECT * FROM (SELECT COD_CLASSE FROM CLASSE_AGENDA) AS CS (COD_CLASSE); -- uma união -- retornar todas as linhas das colunas NUM_DEP e GERENTE -- da tabela ORG -- e (1,2) e (3,4) -- NUM_DEP e GERENTE são colunas do tipo SMALLINT. SELECT NUM_DEP, GERENTE FROM ORG UNION ALL VALUES (1,2), (3,4); -- uma expressão de valores VALUES (1,2,3); -- Listar os números dos empregados (NUM_EMP) -- de todos os empregados na tabela EMPREGADOS -- cujo número do departamento (DEP_TRAB) começa por 'E', ou -- quem está alocado a projetos na tabela ATIV_EMP -- cujo número do projetor (NUM_PROJ) é igual a -- 'MA2100', 'MA2110' ou 'MA2112'. SELECT NUM_EMP FROM EMPREGADOS WHERE DEP_TRAB LIKE 'E%' UNION SELECT NUM_EMP FROM ATIV_EMP WHERE NUM_PROJ IN('MA2100', 'MA2110', 'MA2112'); -- Realizar a mesma consulta do exemplo anterior -- e "marcar" as linhas da tabela EMPREGADOS com 'emp' e -- as linhas da tabela ATIV_EMP com 'ativ_emp'. -- Diferentemente do resultado do exemplo anterior, -- esta consulta pode retornar o mesmo NUM_EMP mais de uma vez, -- identificando de que tabela veio pela "marca" associada. SELECT NUM_EMP, 'emp' FROM EMPREGADOS WHERE DEP_TRAB LIKE 'E%' UNION SELECT NUM_EMP, 'ativ_emp' FROM ATIV_EMP WHERE NUM_PROJ IN('MA2100', 'MA2110', 'MA2112'); -- Realizar a mesma consulta do exemplo anterior, -- porém utilizando UNION ALL para que as linhas -- duplicadas não sejam eliminadas. SELECT NUM_EMP FROM EMPREGADOS WHERE DEP_TRAB LIKE 'E%' UNION ALL SELECT NUM_EMP FROM ATIV_EMP WHERE NUM_PROJ IN('MA2100', 'MA2110', 'MA2112'); -- Realizar a mesma consulta do exemplo anterior, -- incluindo dois empregados adicionais que no -- momento não se encontram em nenhuma tabela, -- e marcar estas linhas como "nova". SELECT NUM_EMP, 'emp' FROM EMPREGADOS WHERE DEP_TRAB LIKE 'E%' UNION SELECT NUM_EMP, 'ativ_emp' FROM ATIV_EMP WHERE NUM_PROJ IN('MA2100', 'MA2110', 'MA2112') UNION VALUES ('NEWAAA', 'nova'), ('NEWBBB', 'nova');