Operadores de conjuntos

Os operadores de conjuntos permitem que as consultas sejam combinadas.

Neste tópico:

Sintaxe geral

[ ( ] <query> [ ) ] { INTERSECT | { MINUS | EXCEPT } | UNION [ ALL ] } [ ( ] <query> [ ) ]
[ ORDER BY ... ]
[ LIMIT ... ]
Copy

Notas de uso geral

  • Cada consulta em si pode conter operadores de consulta para permitir que qualquer quantidade de expressões de consulta possa ser combinada com operadores de conjunto.

  • As cláusulas ORDER BY e LIMIT / FETCH são aplicadas ao resultado do operador de conjunto.

  • Ao utilizar esses operadores:

    • Certifique-se de que cada consulta selecione o mesmo número de colunas.

    • Certifique-se de que o tipo de dados de cada coluna seja consistente entre as linhas de diferentes fontes. Um dos exemplos na seção Exemplos abaixo ilustra o problema potencial e a solução quando os tipos de dados não correspondem.

    • Em geral, os “significados”, assim como os tipos de dados, das colunas devem corresponder. O elemento a seguir não produzirá os resultados desejados:

      SELECT LastName, FirstName FROM employees
      UNION ALL
      SELECT FirstName, LastName FROM contractors;
      
      Copy

      O risco de erro aumenta ao utilizar o asterisco para especificar todas as colunas de uma tabela, por exemplo:

      SELECT * FROM table1
      UNION ALL
      SELECT * FROM table2;
      
      Copy

      Se as tabelas tiverem o mesmo número de colunas, mas as colunas não estiverem na mesma ordem, os resultados da consulta provavelmente estarão incorretos.

    • Os nomes das colunas de saída são baseados nos nomes das colunas da primeira consulta. Por exemplo, a seguinte consulta:

      SELECT LastName, FirstName FROM employees
      UNION ALL
      SELECT FirstName, LastName FROM contractors;
      
      Copy

      se comporta como se a consulta fosse:

      SELECT LastName, FirstName FROM employees
      UNION ALL
      SELECT FirstName AS LastName, LastName AS FirstName FROM contractors;
      
      Copy
  • A precedência dos operadores do conjunto corresponde aos padrões ANSI e ISO SQL:

    • Os operadores UNION [ALL] e MINUS (EXCEPT) têm a mesma precedência.

    • O operador INTERSECT tem maior precedência que UNION [ALL] e MINUS (EXCEPT).

    Os operadores de igual precedência são processados da esquerda para a direita.

    Você pode usar parênteses para forçar as expressões a serem avaliadas em uma ordem diferente.

    Nem todos os fornecedores de banco de dados seguem o padrão ANSI/ISO para precedência dos operadores definidos. Snowflake recomenda o uso de parênteses para especificar a ordem de avaliação, especialmente se você estiver portando código de outro fornecedor para Snowflake, ou escrevendo código que você pode executar em outros bancos de dados, assim como em Snowflake.

INTERSECT

Retorna linhas do conjunto de resultados de uma consulta que também aparecem no conjunto de resultados de outra consulta, com eliminação de duplicatas.

Sintaxe

SELECT ...
INTERSECT
SELECT ...
Copy

MINUS , EXCEPT

Remove linhas do conjunto de resultados de uma consulta que também aparecem no conjunto de resultados de outra consulta, com eliminação de duplicatas.

As palavras-chave MINUS e EXCEPT têm o mesmo significado e podem ser usadas de forma intercambiável.

Sintaxe

SELECT ...
MINUS
SELECT ...

SELECT ...
EXCEPT
SELECT ...
Copy

UNION [ ALL ]

Combina os conjuntos de resultados de duas consultas:

  • UNION combina com eiminação de duplicatas.

  • UNION ALL combina sem eliminação de duplicatas.

O padrão é UNION (ou seja, eliminação de duplicatas).

Sintaxe

SELECT ...
UNION [ ALL ]
SELECT ...
Copy

Exemplos

Este exemplo demonstra o uso básico do operador UNION. Ele também demonstra um problema potencial quando os tipos de dados não correspondem, então fornece a solução.

Comece criando as tabelas e inserindo alguns dados:

CREATE TABLE t1 (v VARCHAR);
CREATE TABLE t2 (i INTEGER);
INSERT INTO t1 (v) VALUES ('Adams, Douglas');
INSERT INTO t2 (i) VALUES (42);
Copy

Execute uma operação UNION com diferentes tipos de dados:

SELECT v FROM t1    -- VARCHAR
UNION
SELECT i FROM t2    -- INTEGER
;
Copy

Saída:

100038 (22018): Numeric value 'Adams, Douglas' is not recognized
Copy

Agora use conversão explícita para converter as entradas em um tipo compatível:

SELECT v::VARCHAR FROM t1
UNION
SELECT i::VARCHAR FROM t2;
Copy

Saída:

+----------------+
| V::VARCHAR     |
|----------------|
| Adams, Douglas |
| 42             |
+----------------+
Copy