Entenda UNION e UNION ALL no SQL

Entenda UNION e UNION ALL no SQL

26 de julho de 2021 0 Por Ramos de Souza Janones

Entenda as diferenças e usos práticos em SQL sobre UNION e UNION ALL.

  • UNION é uma operação de coleções de elementos que resulta em um terceiro conjunto;
  • UNION ALL é uma operação de coleções de elementos resultando em uma bag.

Aqui, tanto conjunto como bag são coleções de elementos. A diferença entre eles é dada pela “operação de soma” de elementos a uma coleção pré-existente. Vou definir como “soma”:

el + C = R

Onde el é um elemento qualquer, C é a coleção pré-existente e R é a coleção resultante da operação, que contém em sua totalidade C e também tem como elemento el.

Se el não existir previamente em C, então as operações com conjunto e bag são idênticas. Agora, se el já existir previamente em C, a soma com um conjunto resultará em R == C, não afetando o resultante. Porém a bag é alterada com a adição de el, portanto R != C.

De certo modo, podemos dizer que a bag é uma coleção de elementos que admite repetição, já conjunto não admite repetição.





Queremos criar melhores conteúdos:

Criamos uma pesquisa sobre o seu perfil profissional:
  1. Principais objetivos;
  2. Principais Problemas no seu dia a dia;
  3. Principais Alegrias.
Participe: Pesquisa Ramos da Informática – Queremos te conhecer melhor.

LEIA TAMBÉM:

SQL e Regex – Entenda quando e como usar em instruções SQL

VIEWS SQL- O que são, vantagens e desvantagens?

SQL – Quais as diferença entre LIKE, IN e BETWEEN?

UNION combina dados de uma tabela com outra linearmente. Não é como um JOIN que se faz por relacionamento, ele faz uma “soma” simples da linhas de uma tabela com outra(s). As colunas das tabelas envolvidas precisam ser as mesmas (quantidade e tipos nas devidas posições). É como colocar uma embaixo da outra.

LEIA TAMBÉM:  Cursos de programação grátis e processos seletivos

Veja SQLFiddle para UNION e SQLFiddle para UNION ALL.

Existem casos que pode complicar. Se por exemplo tiver uma coluna UNIQUE, incluindo aí a PRIMARY KEY, pode não dar o resultado esperado, então nesses casos uma coluna assim não deveria fazer parte do SELECTVeja no SQLFiddle.

Caso no futuro este Fiddle não exista mais, seguem os códigos:

create table tabela1 (
  id int(6) primary key auto_increment,
  nome varchar(10) not null,
  salario decimal);
  
create table tabela2 (
  id int(6) primary key auto_increment,
  nome varchar(10) not null,
  salario decimal);
  
insert into tabela1 (nome, salario) values
  ("joão", 100.00),
  ("josé", 120.00),
  ("maria", 200.00),
  ("joão", 150.00);
  
insert into tabela2 (nome, salario) values
  ("joão", 100.00),
  ("josé", 120.00),
  ("manuel", 200.00),
  ("joão", 150.00);

select * from tabela1 where salario > 100.00
union
select * from tabela2;

select * from tabela1 where salario > 100.00
union all
select * from tabela2;

select * from tabela1 where salario > 100.00
union
select * from tabela2;

Exemplo de UNION no SQL

Como exemplo vamos nos basear na modelagem a seguir:

LEIA TAMBÉM:  Principais diferenças entre MongoDB e MySQL ou outro RDBMS?

Vamos supor que é preciso resgatar o nome e código de todos os correntistas, assim como se ele é “supervisor”, “vendedor” ou “cliente”. A chave estrangeira em “conta_corrente” é cd_usuario, que por sua vez se liga com cd_cliente, ou cd_vendedor, ou cd_supervisor, dependendo da muliplexação. No meu caso, cada correntista só pode ter no máximo uma conta corrente. A consulta ficaria assim:

SELECT cd_usuario, "cliente" AS tp_correntista, nm_cliente AS nm_correntista
FROM conta_corrente cc INNER JOIN
    cliente c ON (c.cd_cliente = cc.cd_usuario)
WHERE cc.tp_conta = 'c'
UNION
SELECT cd_usuario, "vendedor" AS tp_correntista, nm_vendedor AS nm_correntista
FROM conta_corrente cc INNER JOIN
    vendedor v ON (v.cd_vendedor = cc.cd_usuario)
WHERE cc.tp_conta = 'v'
UNION
SELECT cd_usuario, "supervisor" AS tp_correntista, nm_supervisor AS nm_correntista
FROM conta_corrente cc INNER JOIN
    supervisor s ON (s.cd_supervisor = cc.cd_usuario)
WHERE cc.tp_conta = 's'

Pronto, a consulta retorna um conjunto como esperado. Agora, notou como não é possível que, por acaso, haja uma igualdade de tuplas entre, digamos, a primeira consulta e a segunda consulta? Isso porque todos os elementos da primeira consulta terão como segundo elemento de suas tuplas o valor “cliente”, já os da segunda consulta o valor na mesma posição seria “vendedor”. Além disso, como cd_cliente é chave primária da tabela cliente e cada cliente nesse modelo só está atrelado a no máximo um elemento da tabela conta_corrente, então não tem choque de tuplas dentro de cada consulta individual, portanto cada uma das 3 consultas acima resulta num conjunto.

LEIA TAMBÉM:  MySQL - Manter o formato Date e DateTime em formato brasileiro

Como já temos 3 conjuntos, e temos garantia que nenhum desses conjuntos tem elemento em comum com outro conjunto, a operação de “soma” terá o mesmo resultado final que a “soma” de bags. Portanto, em casos assim, o uso do UNION ALL garante o resultado desejado e também garante uma melhor performance (teoricamente pelo menos).

A consulta então pode ser reescrita assim:

SELECT cd_usuario, "cliente" AS tp_correntista, nm_cliente AS nm_correntista
FROM conta_corrente cc INNER JOIN
    cliente c ON (c.cd_cliente = cc.cd_usuario)
WHERE cc.tp_conta = 'c'
UNION ALL
SELECT cd_usuario, "vendedor" AS tp_correntista, nm_vendedor AS nm_correntista
FROM conta_corrente cc INNER JOIN
    vendedor v ON (v.cd_vendedor = cc.cd_usuario)
WHERE cc.tp_conta = 'v'
UNION ALL
SELECT cd_usuario, "supervisor" AS tp_correntista, nm_supervisor AS nm_correntista
FROM conta_corrente cc INNER JOIN
    supervisor s ON (s.cd_supervisor = cc.cd_usuario)
WHERE cc.tp_conta = 's'

A seguir um gráfico que resume o uso de UNION e UNION ALL utilizando o SQL:

LEIA TAMBÉM:

Entenda Views em SQL, vantagens e desvantagens

O que é normalização de banco de dados?

SQL – Not IN ou Not EXISTS quando usar?

Entenda SQL JOIN: Inner, Left, Right, Outer/Full e Cross Join

Tem mais dicas sobre SQL, em especial UNION? Então posta nos comentários.

VOCÊ ESTÁ NA SEÇÃO: » Banco de Dados

 

votes
Article Rating

E-Zine Ramos da Informática

* indicates required

View previous campaigns.