- Categorias:
JOIN¶
Uma operação JOIN
combina linhas de duas tabelas (ou outras fontes semelhantes a tabelas, como visualizações ou funções de tabela) para criar uma nova linha combinada que pode ser usada na consulta. Para uma explicação conceitual das junções, consulte Trabalho com junções.
Este tópico descreve como usar a subcláusula JOIN
na cláusula FROM. A subcláusula JOIN
especifica, explícita ou implicitamente, como relacionar as linhas em uma tabela com as linhas correspondentes na outra tabela. Você também pode usar a subcláusula ASOF JOIN, que é usada para unir dados de séries temporais em colunas de carimbo de data/hora quando seus valores seguem um ao outro, precedem um ao outro ou correspondem exatamente.
Embora a forma recomendada de juntar tabelas seja usar JOIN
com a subcláusula ON
da cláusula FROM
, uma forma alternativa de fazer a junção das tabelas é usando a cláusula WHERE
. Para obter mais detalhes, consulte a documentação da cláusula WHERE.
Sintaxe¶
Use uma das seguintes opções:
SELECT ...
FROM <object_ref1> [
{
INNER
| { LEFT | RIGHT | FULL } [ OUTER ]
}
[ DIRECTED ]
]
JOIN <object_ref2>
[ ON <condition> ]
[ ... ]
SELECT *
FROM <object_ref1> [
{
INNER
| { LEFT | RIGHT | FULL } [ OUTER ]
}
[ DIRECTED ]
]
JOIN <object_ref2>
[ USING( <column_list> ) ]
[ ... ]
SELECT ...
FROM <object_ref1> [
{
NATURAL [
{
INNER
| { LEFT | RIGHT | FULL } [ OUTER ]
}
[ DIRECTED ]
]
| CROSS [ DIRECTED ]
}
]
JOIN <object_ref2>
[ ... ]
Parâmetros¶
object_ref1
eobject_ref2
Cada referência de objeto é uma fonte de dados em tabela ou forma de tabela.
JOIN
Use a palavra-chave
JOIN
para especificar que as tabelas devem ser unidas. CombineJOIN
com outras palavras-chave relacionadas à junção (por exemplo,INNER
ouOUTER
) para especificar o tipo de junção.A semântica das junções é a seguinte (para brevidade, este tópico usa
o1
eo2
paraobject_ref1
eobject_ref2
, respectivamente).Tipo de junção
Semântica
o1 INNER JOIN o2
Para cada linha de
o1
, é produzida uma linha para cada linha deo2
correspondente de acordo com a subcláusulaON condition
. (Você também pode usar uma vírgula para especificar uma junção interna. Para obter um exemplo, consulte a seção de exemplos abaixo.) Se você usarINNER JOIN
sem a cláusulaON
, ou se usar uma vírgula sem uma cláusulaWHERE
, o resultado será o mesmo que usarCROSS JOIN
: um produto cartesiano; cada linha deo1
emparelhada com cada linha deo2
.o1 LEFT OUTER JOIN o2
O resultado da junção interna é aumentado com uma linha para cada linha de
o1
que não tenha correspondências emo2
. As colunas de resultados referentes ao2
contêm nulos.o1 RIGHT OUTER JOIN o2
O resultado da junção interna é aumentado com uma linha para cada linha de
o2
que não tenha correspondências emo1
. As colunas de resultados referentes ao1
contêm nulos.o1 FULL OUTER JOIN o2
Retorna todas as linhas unidas, mais uma linha para cada linha sem correspondência do lado esquerdo (estendida com nulos à direita), mais uma linha para cada linha sem correspondência do lado direito (estendida com nulos à esquerda).
o1 CROSS JOIN o2
Para cada combinação possível de linhas de
o1
eo2
(ou seja, produto cartesiano), a tabela unida contém uma linha que consiste em todas as colunas emo1
seguida de todas as colunas emo2
. UmCROSS JOIN
não pode ser combinado com uma cláusulaON condition
. No entanto, você pode usar uma cláusulaWHERE
para filtrar os resultados.o1 NATURAL JOIN o2
A
NATURAL JOIN
é idêntica a umaJOIN
explícita nas colunas comuns das duas tabelas, exceto que as colunas comuns são incluídas apenas uma vez na saída. (Uma junção natural considera que colunas com o mesmo nome, mas em tabelas diferentes, contêm dados correspondentes). Para exemplos, consulte a seção de exemplos. ANATURAL JOIN
pode ser combinada com umOUTER JOIN
. UmaNATURAL JOIN
não pode ser combinada com uma cláusulaON condition
porque a condiçãoJOIN
já está implícita. No entanto, você pode usar uma cláusulaWHERE
para filtrar os resultados.A palavra-chave
DIRECTED
especifica uma junção direcionada, que impõe a ordem de junção das tabelas. A primeira tabela, ou da esquerda, é verificada antes da segunda tabela, ou da direita. Por exemplo,o1 INNER DIRECTED JOIN o2
examina a tabelao1
antes da tabelao2
. Junções direcionadas são úteis nas seguintes situações:Você está migrando cargas de trabalho para o Snowflake com diretrizes de ordem de junção.
Você deseja melhorar o desempenho verificando tabelas de junção em uma ordem específica.
Nota
A junção direcionada é um recurso em versão preliminar disponível para todas as contas.
Padrão:
INNER JOIN
Se a palavra
JOIN
for usada sem especificarINNER
ouOUTER
, então oJOIN
é uma junção interna.Se a palavra-chave
DIRECTED
for adicionada, o tipo de junção (por exemplo,INNER
ouOUTER
) é necessário.Consulte também:
ON condition
Uma expressão booleana que define as linhas dos dois lados da
JOIN
que são consideradas iguais, por exemplo:ON object_ref2.id_number = object_ref1.id_number
As condições são discutidas com mais detalhes na documentação da cláusula WHERE.
A cláusula
ON
é proibida paraCROSS JOIN
.A cláusula
ON
é desnecessária (e proibida) paraNATURAL JOIN
porque as colunas de junção estão implícitas.Para outras junções, a cláusula
ON
é opcional. No entanto, omitir a cláusulaON
resulta em um produto cartesiano (cada linha deobject_ref1
emparelhada com cada linha deobject_ref2
). Um produto cartesiano pode criar um volume de produção muito grande, quase todos os quais consistem em pares de linhas que não estão realmente relacionados, o que consome muitos recursos e, muitas vezes, é um erro do usuário.USING( column_list )
Uma lista de colunas em comum entre as duas tabelas que estão sendo unidas. Essas colunas são usadas como colunas de junção. As colunas devem ter o mesmo nome e significado em cada uma das tabelas que estão sendo unidas.
Por exemplo, suponha que a instrução SQL contenha:
... o1 JOIN o2 USING (key_column)
No caso simples, isto seria equivalente a:
... o1 JOIN o2 ON o2.key_column = o1.key_column
Na sintaxe padrão de JOIN, a lista de projeção (a lista de colunas e outras expressões após a palavra-chave SELECT) é
*
. Isto faz com que a consulta retorne okey_column
exatamente uma vez. As colunas são retornadas na seguinte ordem:As colunas na cláusula
USING
na ordem especificada.As colunas esquerdas da tabela não especificadas na cláusula
USING
.As colunas direitas da tabela não especificadas na cláusula
USING
.
Para exemplos de uso padrão e não padrão, consulte a seção exemplos.
Notas de uso¶
As seguintes restrições se aplicam a funções de tabela diferentes de UDTFs SQL:
Não é possível especificar a cláusula
ON
,USING
ouNATURAL JOIN
em uma função de tabela lateral, diferente de SQL UDTF).Por exemplo, a seguinte sintaxe não é permitida:
SELECT ... FROM my_table JOIN TABLE(FLATTEN(input=>[col_a])) ON ... ;
SELECT ... FROM my_table INNER JOIN TABLE(FLATTEN(input=>[col_a])) ON ... ;
SELECT ... FROM my_table JOIN TABLE(my_js_udtf(col_a)) ON ... ;
SELECT ... FROM my_table INNER JOIN TABLE(my_js_udtf(col_a)) ON ... ;
Não é possível especificar a cláusula
ON
,USING
ouNATURAL JOIN
em uma junção lateral externa a uma função de tabela, diferente de SQL UDTF).Por exemplo, a seguinte sintaxe não é permitida:
SELECT ... FROM my_table LEFT JOIN TABLE(FLATTEN(input=>[a])) ON ... ;
SELECT ... FROM my_table FULL JOIN TABLE(FLATTEN(input=>[a])) ON ... ;
SELECT ... FROM my_table LEFT JOIN TABLE(my_js_udtf(a)) ON ... ;
SELECT ... FROM my_table FULL JOIN TABLE(my_js_udtf(a)) ON ... ;
Usar essa sintaxe resulta no seguinte erro:
000002 (0A000): Unsupported feature 'lateral table function called with OUTER JOIN syntax or a join predicate (ON clause)'
Essas restrições não se aplicam se você usar uma vírgula em vez de uma palavra-chave JOIN:
SELECT ... FROM my_table, TABLE(FLATTEN(input=>[col_a])) ON ... ;
Exemplos¶
Muitos dos exemplos de JOIN
usam duas tabelas: t1
e t2
. Crie estas tabelas e insira os dados:
CREATE TABLE t1 (col1 INTEGER);
INSERT INTO t1 (col1) VALUES
(2),
(3),
(4);
CREATE TABLE t2 (col1 INTEGER);
INSERT INTO t2 (col1) VALUES
(1),
(2),
(2),
(3);
Os exemplos a seguir executam consultas com junções:
Executar uma consulta que combine as junções na cláusula FROM
Executar consultas com junções que utilizam a cláusula USING
Execução de uma consulta com uma junção interna¶
O exemplo a seguir executa uma consulta com uma junção interna:
SELECT t1.col1, t2.col1
FROM t1 INNER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
+------+------+
Execute a mesma consulta com uma junção direcionada ao interno para impor a ordem de junção para que a tabela esquerda seja verificada primeiro:
Nota
A junção direcionada é um recurso em versão preliminar disponível para todas as contas.
SELECT t1.col1, t2.col1
FROM t1 INNER DIRECTED JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
+------+------+
Execução de uma consulta com uma junção externa esquerda¶
O exemplo a seguir executa uma consulta com uma junção externa esquerda:
SELECT t1.col1, t2.col1
FROM t1 LEFT OUTER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
Na saída, há um valor NULL para a linha na tabela t1
que não tem uma linha correspondente na tabela t2
:
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
| 4 | NULL |
+------+------+
Execução de uma consulta com uma junção externa direita¶
O exemplo a seguir executa uma consulta com uma junção externa direita:
SELECT t1.col1, t2.col1
FROM t1 RIGHT OUTER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
Na saída, há um valor NULL para a linha na tabela t1
que não tem uma linha correspondente na tabela t2
.
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
| NULL | 1 |
+------+------+
Execução de uma consulta com uma junção externa completa¶
O exemplo a seguir executa uma consulta com uma junção externa completa:
SELECT t1.col1, t2.col1
FROM t1 FULL OUTER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
Cada tabela tem uma linha que não tem uma linha correspondente na outra tabela, portanto a saída contém duas linhas com valores NULL:
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
| 4 | NULL |
| NULL | 1 |
+------+------+
Execução de uma consulta com uma junção cruzada¶
O exemplo a seguir executa uma consulta com uma junção cruzada:
Nota
Uma junção cruzada não tem uma cláusula ON.
SELECT t1.col1, t2.col1
FROM t1 CROSS JOIN t2
ORDER BY 1, 2;
A saída mostra que a consulta produz um produto cartesiano:
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 1 |
| 2 | 2 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 2 |
| 3 | 2 |
| 3 | 3 |
| 4 | 1 |
| 4 | 2 |
| 4 | 2 |
| 4 | 3 |
+------+------+
Uma junção cruzada pode ser filtrada por uma cláusula WHERE
, como mostrado no seguinte exemplo:
SELECT t1.col1, t2.col1
FROM t1 CROSS JOIN t2
WHERE t2.col1 = t1.col1
ORDER BY 1, 2;
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
+------+------+
Execução de uma consulta com uma junção natural¶
O exemplo a seguir mostra uma consulta com uma junção natural. Primeiro, crie duas tabelas e insira os dados:
CREATE OR REPLACE TABLE d1 (
id NUMBER,
name VARCHAR);
INSERT INTO d1 (id, name) VALUES
(1,'a'),
(2,'b'),
(4,'c');
CREATE OR REPLACE TABLE d2 (
id NUMBER,
value VARCHAR);
INSERT INTO d2 (id, value) VALUES
(1,'xx'),
(2,'yy'),
(5,'zz');
Execute uma consulta com uma junção natural:
SELECT *
FROM d1 NATURAL INNER JOIN d2
ORDER BY id;
A saída mostra que uma junção natural produz a mesma saída da junção interna correspondente, exceto que a saída não inclui uma segunda cópia da coluna de junção:
+----+------+-------+
| ID | NAME | VALUE |
|----+------+-------|
| 1 | a | xx |
| 2 | b | yy |
+----+------+-------+
O exemplo a seguir mostra que você pode combinar junções naturais com junções externas:
SELECT *
FROM d1 NATURAL FULL OUTER JOIN d2
ORDER BY id;
+----+------+-------+
| ID | NAME | VALUE |
|----+------+-------|
| 1 | a | xx |
| 2 | b | yy |
| 4 | c | NULL |
| 5 | NULL | zz |
+----+------+-------+
Executar uma consulta que combine as junções na cláusula FROM¶
Você pode combinar na cláusula FROM
. Crie uma terceira tabela:
CREATE TABLE t3 (col1 INTEGER);
INSERT INTO t3 (col1) VALUES
(2),
(6);
Execute uma consulta que una duas junções na cláusula FROM:
SELECT t1.*, t2.*, t3.*
FROM t1
LEFT OUTER JOIN t2 ON (t1.col1 = t2.col1)
RIGHT OUTER JOIN t3 ON (t3.col1 = t2.col1)
ORDER BY t1.col1;
+------+------+------+
| COL1 | COL1 | COL1 |
|------+------+------|
| 2 | 2 | 2 |
| 2 | 2 | 2 |
| NULL | NULL | 6 |
+------+------+------+
Em tal consulta, os resultados são determinados com base nas junções que ocorrem da esquerda para a direita, embora o otimizador possa reordenar as junções se uma ordem de junção diferente produzir o mesmo resultado. Se a junção externa direita tiver que ocorrer antes da junção externa esquerda, então escreva a consulta da seguinte maneira:
SELECT t1.*, t2.*, t3.*
FROM t1
LEFT OUTER JOIN
(t2 RIGHT OUTER JOIN t3 ON (t3.col1 = t2.col1))
ON (t1.col1 = t2.col1)
ORDER BY t1.col1;
+------+------+------+
| COL1 | COL1 | COL1 |
|------+------+------|
| 2 | 2 | 2 |
| 2 | 2 | 2 |
| 3 | NULL | NULL |
| 4 | NULL | NULL |
+------+------+------+
Executar consultas com junções que utilizam a cláusula USING¶
Os próximos dois exemplos mostram o uso padrão (ISO 9075) e não padrão da cláusula USING
. Ambos são suportados pelo Snowflake.
Este primeiro exemplo mostra o uso padrão. Especificamente, a lista de projeção contém exatamente *
.
WITH
l AS (
SELECT 'a' AS userid
),
r AS (
SELECT 'b' AS userid
)
SELECT *
FROM l LEFT JOIN r USING(userid);
Mesmo que a consulta de exemplo una duas tabelas, e cada tabela tenha uma coluna, e a consulta peça todas as colunas, a saída terá uma coluna, não duas:
+--------+
| USERID |
|--------|
| a |
+--------+
O exemplo a seguir mostra o uso não padrão. A lista de projeção contém algo diferente de *
.
WITH
l AS (
SELECT 'a' AS userid
),
r AS (
SELECT 'b' AS userid
)
SELECT l.userid as UI_L,
r.userid as UI_R
FROM l LEFT JOIN r USING(userid);
A saída contém duas colunas, e a segunda coluna contém um valor da segunda tabela ou NULL:
+------+------+
| UI_L | UI_R |
|------+------|
| a | NULL |
+------+------+