- 카테고리:
JOIN¶
JOIN
작업은 두 테이블(또는 뷰나 테이블 함수와 같은 다른 테이블 유사 소스)의 행을 결합하여, 쿼리에 사용할 수 있는 결합된 새 행을 만듭니다. 조인에 대한 개념 설명은 조인 관련 작업하기 섹션을 참조하세요.
이 항목에서는 FROM 절의 JOIN
하위 절을 사용하는 방법에 대해 설명합니다. JOIN
하위 절은 한 테이블의 행을 다른 테이블의 해당 행과 관련시키는 방법을 명시적으로 또는 암시적으로 지정합니다. 값이 밀접하게 서로의 뒤에 오거나, 앞에 오거나, 정확히 일치하는 경우 타임스탬프 열의 시계열 데이터를 조인하는 데 사용되는 ASOF JOIN 하위 절을 사용할 수도 있습니다.
테이블을 조인하는 데 권장되는 방법은 FROM
절의 ON
하위 절과 함께 JOIN
을 사용하는 것이지만, 테이블을 조인하는 다른 방법은 WHERE
절을 사용하는 것입니다. 자세한 내용은 WHERE 절에 대한 설명서를 참조하십시오.
구문¶
다음 중 하나를 사용하십시오.
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>
[ ... ]
매개 변수¶
object_ref1
및object_ref2
각 오브젝트 참조는 테이블 또는 테이블과 유사한 데이터 소스입니다.
JOIN
JOIN
키워드를 사용하여 테이블을 조인해야 함을 지정할 수 있습니다.JOIN
을 다른 조인 관련 키워드(예:INNER
또는OUTER
)와 결합하여 조인 유형을 지정할 수 있습니다.조인의 의미 체계는 다음과 같습니다(간결함을 위해 이 항목에서는
o1
및o2
에 대해 각각object_ref1
및object_ref2
를 사용함).조인 유형
의미 체계
o1 INNER JOIN o2
o1
의 각 행의 경우,ON condition
하위 절에 따라 일치하는o2
의 각 행에 대해 행이 생성됩니다. (쉼표를 사용하여 내부 조인을 지정할 수도 있습니다. 예제에 대해서는 아래의 예제 섹션 을 참조하세요.)ON
절 없이INNER JOIN
을 사용하는 경우(또는WHERE
절 없이 쉼표를 사용하는 경우), 결과는CROSS JOIN`[즉, 데카르트 곱(:samp:`{o1}
의 모든 행은o2
의 모든 행과 쌍을 이룸)]을 사용하는 것과 동일합니다.o1 LEFT OUTER JOIN o2
내부 조인의 결과는
o1
에 일치 항목이 없는o2
의 각 행에 대한 행으로 증가됩니다.o2
를 참조하는 결과 열에 null이 포함되어 있습니다.o1 RIGHT OUTER JOIN o2
내부 조인의 결과는
o2
에 일치 항목이 없는o1
의 각 행에 대한 행으로 증가됩니다.o1
를 참조하는 결과 열에 null이 포함되어 있습니다.o1 FULL OUTER JOIN o2
조인된 모든 행, 그리고 일치하지 않는 왼쪽 행(오른쪽이 null로 확장됨)에 대한 행 하나, 그리고 일치하지 않는 오른쪽 행(왼쪽이 null로 확장됨)에 대한 행 하나를 반환합니다.
o1 CROSS JOIN o2
o1
및o2
의 가능한 모든 행 조합(즉, 데카르트 곱)의 경우, 조인된 테이블에는o1
의 모든 열에 이어o2
의 모든 열로 구성된 행이 포함됩니다.CROSS JOIN
은ON condition
절과 결합할 수 없습니다. 그러나WHERE
절을 사용하여 결과를 필터링할 수 있습니다.o1 NATURAL JOIN o2
NATURAL JOIN
은 공통 열이 출력에 한 번만 포함된다는 점을 제외하고는, 두 테이블의 공통 열에 대한 명시적JOIN
과 동일합니다. (자연 조인은 이름이 같으나 테이블이 다른 열에 해당 데이터가 포함되어 있다고 가정합니다.) 예제에 대해서는 예제 섹션 을 참조하세요.NATURAL JOIN
은OUTER JOIN
과 결합할 수 있습니다.JOIN
조건이 이미 내포되어 있으므로NATURAL JOIN
을ON condition
절과 결합할 수 없습니다. 그러나WHERE
절을 사용하여 결과를 필터링할 수 있습니다.DIRECTED
키워드는 테이블의 조인 순서를 적용하는 *방향성 조인*을 지정합니다. 첫 번째 또는 왼쪽 테이블이 두 번째 또는 오른쪽 테이블보다 먼저 스캔됩니다. 예를 들어,o1 INNER DIRECTED JOIN o2
은o2
테이블을 스캔하기 전에 먼저o1
테이블을 스캔합니다. 방향성 조인은 다음과 같은 상황에서 유용합니다.조인 순서 지시문이 있는 워크로드를 Snowflake로 마이그레이션합니다.
특정 순서로 조인 테이블을 스캔하여 성능을 개선하려고 합니다.
참고
방향성 조인은 모든 계정에서 사용할 수 있는 미리 보기 기능 입니다.
기본값:
INNER JOIN
JOIN
또는INNER
를 지정하지 않고OUTER
단어를 사용하는 경우,JOIN
은 내부 조인입니다.DIRECTED
키워드가 추가된 경우, 조인 유형(예:INNER
또는OUTER
)은 필수입니다.참고 항목:
ON condition
일치하는 것으로 간주되는
JOIN
의 두 측면에서 행을 정의하는 부울 식 입니다. 예를 들면 다음과 같습니다.ON object_ref2.id_number = object_ref1.id_number
조건은 WHERE 절 문서에서 더 자세히 설명합니다.
ON
절은CROSS JOIN
에는 금지됩니다.NATURAL JOIN
에는 조인 열은 내포되어 있으므로ON
절이 필요하지 않으며 금지됩니다.다른 조인의 경우,
ON
절은 선택 사항입니다. 그러나ON
절을 생략하면 데카르트 곱이 생성됩니다(object_ref1
의 모든 행은object_ref2
의 모든 행과 쌍을 이룸). 데카르트 곱은 매우 많은 양의 출력을 생성할 수 있으며, 그중 거의 모두는 실제로는 관련되지 않은 행 쌍으로 구성됩니다. 이는 많은 리소스를 사용하며, 사용자 오류인 경우가 많습니다.USING( column_list )
조인되는 두 테이블 사이의 공통 열 목록입니다. 이러한 열은 조인 열로 사용됩니다. 열은 조인되는 각 테이블에서 동일한 이름과 의미를 가져야 합니다.
예를 들어, SQL 문에 다음이 포함되어 있다고 가정합니다.
... o1 JOIN o2 USING (key_column)
간단한 경우에 이는 다음과 같습니다.
... o1 JOIN o2 ON o2.key_column = o1.key_column
표준 JOIN 구문에서 프로젝션 목록(SELECT 키워드 다음의 열 및 기타 식 목록)은
*
입니다. 이로 인해 쿼리가key_column
을 정확히 한 번 반환합니다. 열은 다음 순서로 반환됩니다.USING
절의 열(지정된 순서대로 반환).USING
절에 지정되지 않은 왼쪽 테이블 열.USING
절에 지정되지 않은 오른쪽 테이블 열.
표준 및 비표준 사용법의 예는 예제 섹션 을 참조하세요.
사용법 노트¶
SQL UDTF 이외의 테이블 함수에는 다음 제한 사항이 적용됩니다.
측면 테이블 함수(SQL UDTF 제외)에는
ON
,USING
또는NATURAL JOIN
절을 지정할 수 없습니다.예를 들어 다음 구문은 허용되지 않습니다.
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 ... ;
테이블 함수(SQL UDTF 제외)에 대한 외부 측면 조인에는
ON
,USING
또는NATURAL JOIN
절을 지정할 수 없습니다.예를 들어 다음 구문은 허용되지 않습니다.
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 ... ;
이 구문을 사용하면 다음 오류가 발생합니다.
000002 (0A000): Unsupported feature 'lateral table function called with OUTER JOIN syntax or a join predicate (ON clause)'
JOIN 키워드가 아닌 쉼표를 사용하는 경우에는 이러한 제한 사항이 적용되지 않습니다.
SELECT ... FROM my_table, TABLE(FLATTEN(input=>[col_a])) ON ... ;
예¶
많은 JOIN
예제에서는 두 개의 테이블 t1
및 t2
를 사용합니다. 이 테이블을 만들고 데이터를 삽입합니다.
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);
다음 예제에서는 조인을 사용하여 쿼리를 실행합니다.
내부 조인으로 쿼리 실행¶
다음 예제에서는 내부 조인을 사용하여 쿼리를 실행합니다.
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 |
+------+------+
내부 방향성 조인으로 동일한 쿼리를 실행하여 왼쪽 테이블이 먼저 스캔되도록 조인 순서를 적용합니다.
참고
방향성 조인은 모든 계정에서 사용할 수 있는 미리 보기 기능 입니다.
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 |
+------+------+
왼쪽 외부 조인으로 쿼리 실행¶
다음 예제에서는 왼쪽 외부 조인을 사용하여 쿼리를 실행합니다.
SELECT t1.col1, t2.col1
FROM t1 LEFT OUTER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
출력을 보면 테이블 t2
에 일치하는 행이 없는 테이블 t1
의 행에 NULL이 있습니다.
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
| 4 | NULL |
+------+------+
오른쪽 외부 조인으로 쿼리 실행¶
다음 예제에서는 오른쪽 외부 조인을 사용하여 쿼리를 실행합니다.
SELECT t1.col1, t2.col1
FROM t1 RIGHT OUTER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
출력을 보면 테이블 t2``에 일치하는 행이 없는 테이블 ``t1
의 행에 NULL 값이 있습니다.
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
| NULL | 1 |
+------+------+
전체 외부 조인으로 쿼리 실행¶
다음 예제에서는 전체 외부 조인을 사용하여 쿼리를 실행합니다.
SELECT t1.col1, t2.col1
FROM t1 FULL OUTER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
각 테이블에는 다른 테이블에서 일치하는 행이 없는 행이 있으므로 출력에는 다음과 같이 NULL 값이 있는 두 개의 행이 포함됩니다.
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
| 4 | NULL |
| NULL | 1 |
+------+------+
크로스 조인으로 쿼리 실행¶
다음 예제에서는 크로스 조인을 사용하여 쿼리를 실행합니다.
참고
크로스 조인에는 ON 절이 없습니다.
SELECT t1.col1, t2.col1
FROM t1 CROSS JOIN t2
ORDER BY 1, 2;
출력은 쿼리를 통해 데카르트 곱이 생성되었음을 보여줍니다.
+------+------+
| 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 |
+------+------+
크로스 조인은 아래 예제와 같이 WHERE
절로 필터링할 수 있습니다.
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 |
+------+------+
자연 조인으로 쿼리 실행¶
다음 예제에서는 자연 조인이 있는 쿼리를 보여줍니다. 먼저, 두 개의 테이블을 만들고 데이터를 삽입합니다.
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');
자연 조인으로 쿼리를 실행합니다.
SELECT *
FROM d1 NATURAL INNER JOIN d2
ORDER BY id;
출력에서는 조인 열의 두 번째 복사본이 포함되지 않는다는 점을 제외하고 자연 조인이 다음과 같이 해당 내부 조인과 동일한 출력을 생성함을 보여줍니다.
+----+------+-------+
| ID | NAME | VALUE |
|----+------+-------|
| 1 | a | xx |
| 2 | b | yy |
+----+------+-------+
다음 예제에서는 자연 조인을 외부 조인과 결합할 수 있음을 보여줍니다.
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 |
+----+------+-------+
FROM 절에서 조인을 결합하는 쿼리 실행¶
FROM
절에서 결합할 수 있습니다. 다음과 같이 세 번째 테이블을 만듭니다.
CREATE TABLE t3 (col1 INTEGER);
INSERT INTO t3 (col1) VALUES
(2),
(6);
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 |
+------+------+------+
이러한 쿼리에서 결과는 왼쪽에서 오른쪽으로 발생하는 조인을 기반으로 결정됩니다(단, 다른 조인 순서가 동일 결과를 생성하는 경우, 최적화 프로그램이 조인을 재정렬할 수 있음). 오른쪽 외부 조인이 왼쪽 외부 조인보다 먼저 발생해야 하는 경우, 쿼리를 다음과 같이 작성합니다.
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 |
+------+------+------+
USING 절을 사용하는 조인으로 쿼리 실행¶
다음 두 예제는 표준(ISO 9075) 및 비표준 USING
절 사용을 보여줍니다. 두 방식 모두 Snowflake에서 지원됩니다.
이 첫 번째 예는 표준 사용법을 보여줍니다. 특히 프로젝션 목록에는 정확히 *
가 포함됩니다.
WITH
l AS (
SELECT 'a' AS userid
),
r AS (
SELECT 'b' AS userid
)
SELECT *
FROM l LEFT JOIN r USING(userid);
예제 쿼리가 두 개의 테이블을 조인하고, 각 테이블에 하나의 열이 있고, 쿼리가 모든 열을 요청하더라도 출력에는 두 개의 열이 아니라 하나의 열이 포함됩니다.
+--------+
| USERID |
|--------|
| a |
+--------+
다음 예제에서는 비표준 사용법을 보여줍니다. 프로젝션 목록에는 *
가 아닌 다른 항목이 있습니다.
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);
출력에는 두 개의 열이 포함되며 두 번째 열에는 두 번째 테이블의 값 또는 NULL이 포함됩니다.
+------+------+
| UI_L | UI_R |
|------+------|
| a | NULL |
+------+------+