카테고리:

쿼리 구문

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> ]
[ ... ]
Copy
SELECT *
FROM <object_ref1> [
                     {
                       INNER
                       | { LEFT | RIGHT | FULL } [ OUTER ]
                     }
                     [ DIRECTED ]
                   ]
                   JOIN <object_ref2>
  [ USING( <column_list> ) ]
[ ... ]
Copy
SELECT ...
FROM <object_ref1> [
                     {
                       NATURAL [
                                 {
                                   INNER
                                   | { LEFT | RIGHT | FULL } [ OUTER ]
                                 }
                                 [ DIRECTED ]
                               ]
                       | CROSS  [ DIRECTED ]
                     }
                   ]
                   JOIN <object_ref2>
[ ... ]
Copy

매개 변수

object_ref1object_ref2

각 오브젝트 참조는 테이블 또는 테이블과 유사한 데이터 소스입니다.

JOIN

JOIN 키워드를 사용하여 테이블을 조인해야 함을 지정할 수 있습니다. JOIN 을 다른 조인 관련 키워드(예: INNER 또는 OUTER)와 결합하여 조인 유형을 지정할 수 있습니다.

조인의 의미 체계는 다음과 같습니다(간결함을 위해 이 항목에서는 o1o2 에 대해 각각 object_ref1object_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

o1o2 의 가능한 모든 행 조합(즉, 데카르트 곱)의 경우, 조인된 테이블에는 o1 의 모든 열에 이어 o2 의 모든 열로 구성된 행이 포함됩니다. CROSS JOINON condition 절과 결합할 수 없습니다. 그러나 WHERE 절을 사용하여 결과를 필터링할 수 있습니다.

o1 NATURAL JOIN o2

NATURAL JOIN 은 공통 열이 출력에 한 번만 포함된다는 점을 제외하고는, 두 테이블의 공통 열에 대한 명시적 JOIN 과 동일합니다. (자연 조인은 이름이 같으나 테이블이 다른 열에 해당 데이터가 포함되어 있다고 가정합니다.) 예제에 대해서는 예제 섹션 을 참조하세요. NATURAL JOINOUTER JOIN 과 결합할 수 있습니다. JOIN 조건이 이미 내포되어 있으므로 NATURAL JOINON condition 절과 결합할 수 없습니다. 그러나 WHERE 절을 사용하여 결과를 필터링할 수 있습니다.

DIRECTED 키워드는 테이블의 조인 순서를 적용하는 *방향성 조인*을 지정합니다. 첫 번째 또는 왼쪽 테이블이 두 번째 또는 오른쪽 테이블보다 먼저 스캔됩니다. 예를 들어, o1 INNER DIRECTED JOIN o2o2 테이블을 스캔하기 전에 먼저 o1 테이블을 스캔합니다. 방향성 조인은 다음과 같은 상황에서 유용합니다.

  • 조인 순서 지시문이 있는 워크로드를 Snowflake로 마이그레이션합니다.

  • 특정 순서로 조인 테이블을 스캔하여 성능을 개선하려고 합니다.

참고

방향성 조인은 모든 계정에서 사용할 수 있는 미리 보기 기능 입니다.

기본값: INNER JOIN

JOIN 또는 INNER 를 지정하지 않고 OUTER 단어를 사용하는 경우, JOIN 은 내부 조인입니다.

DIRECTED 키워드가 추가된 경우, 조인 유형(예: INNER 또는 OUTER)은 필수입니다.

참고 항목:

ON condition

일치하는 것으로 간주되는 JOIN 의 두 측면에서 행을 정의하는 부울 식 입니다. 예를 들면 다음과 같습니다.

ON object_ref2.id_number = object_ref1.id_number
Copy

조건은 WHERE 절 문서에서 더 자세히 설명합니다.

ON 절은 CROSS JOIN 에는 금지됩니다.

NATURAL JOIN 에는 조인 열은 내포되어 있으므로 ON 절이 필요하지 않으며 금지됩니다.

다른 조인의 경우, ON 절은 선택 사항입니다. 그러나 ON 절을 생략하면 데카르트 곱이 생성됩니다(object_ref1 의 모든 행은 object_ref2 의 모든 행과 쌍을 이룸). 데카르트 곱은 매우 많은 양의 출력을 생성할 수 있으며, 그중 거의 모두는 실제로는 관련되지 않은 행 쌍으로 구성됩니다. 이는 많은 리소스를 사용하며, 사용자 오류인 경우가 많습니다.

USING( column_list )

조인되는 두 테이블 사이의 공통 열 목록입니다. 이러한 열은 조인 열로 사용됩니다. 열은 조인되는 각 테이블에서 동일한 이름과 의미를 가져야 합니다.

예를 들어, SQL 문에 다음이 포함되어 있다고 가정합니다.

... o1 JOIN o2
    USING (key_column)
Copy

간단한 경우에 이는 다음과 같습니다.

... o1 JOIN o2
    ON o2.key_column = o1.key_column
Copy

표준 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 ... ;
      
      Copy
      SELECT ... FROM my_table
        INNER JOIN TABLE(FLATTEN(input=>[col_a]))
        ON ... ;
      
      Copy
      SELECT ... FROM my_table
        JOIN TABLE(my_js_udtf(col_a))
        ON ... ;
      
      Copy
      SELECT ... FROM my_table
        INNER JOIN TABLE(my_js_udtf(col_a))
        ON ... ;
      
      Copy
    • 테이블 함수(SQL UDTF 제외)에 대한 외부 측면 조인에는 ON, USING 또는 NATURAL JOIN 절을 지정할 수 없습니다.

      예를 들어 다음 구문은 허용되지 않습니다.

      SELECT ... FROM my_table
        LEFT JOIN TABLE(FLATTEN(input=>[a]))
        ON ... ;
      
      Copy
      SELECT ... FROM my_table
        FULL JOIN TABLE(FLATTEN(input=>[a]))
        ON ... ;
      
      Copy
      SELECT ... FROM my_table
        LEFT JOIN TABLE(my_js_udtf(a))
        ON ... ;
      
      Copy
      SELECT ... FROM my_table
        FULL JOIN TABLE(my_js_udtf(a))
        ON ... ;
      
      Copy

      이 구문을 사용하면 다음 오류가 발생합니다.

      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 ... ;
      
      Copy

많은 JOIN 예제에서는 두 개의 테이블 t1t2 를 사용합니다. 이 테이블을 만들고 데이터를 삽입합니다.

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);
Copy

다음 예제에서는 조인을 사용하여 쿼리를 실행합니다.

내부 조인으로 쿼리 실행

다음 예제에서는 내부 조인을 사용하여 쿼리를 실행합니다.

SELECT t1.col1, t2.col1
  FROM t1 INNER JOIN t2
    ON t2.col1 = t1.col1
  ORDER BY 1,2;
Copy
+------+------+
| 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;
Copy
+------+------+
| 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;
Copy

출력을 보면 테이블 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;
Copy

출력을 보면 테이블 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;
Copy

각 테이블에는 다른 테이블에서 일치하는 행이 없는 행이 있으므로 출력에는 다음과 같이 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;
Copy

출력은 쿼리를 통해 데카르트 곱이 생성되었음을 보여줍니다.

+------+------+
| 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;
Copy
+------+------+
| 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');
Copy

자연 조인으로 쿼리를 실행합니다.

SELECT *
  FROM d1 NATURAL INNER JOIN d2
  ORDER BY id;
Copy

출력에서는 조인 열의 두 번째 복사본이 포함되지 않는다는 점을 제외하고 자연 조인이 다음과 같이 해당 내부 조인과 동일한 출력을 생성함을 보여줍니다.

+----+------+-------+
| ID | NAME | VALUE |
|----+------+-------|
|  1 | a    | xx    |
|  2 | b    | yy    |
+----+------+-------+

다음 예제에서는 자연 조인을 외부 조인과 결합할 수 있음을 보여줍니다.

SELECT *
  FROM d1 NATURAL FULL OUTER JOIN d2
  ORDER BY id;
Copy
+----+------+-------+
| 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);
Copy

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;
Copy
+------+------+------+
| 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;
Copy
+------+------+------+
| 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);
Copy

예제 쿼리가 두 개의 테이블을 조인하고, 각 테이블에 하나의 열이 있고, 쿼리가 모든 열을 요청하더라도 출력에는 두 개의 열이 아니라 하나의 열이 포함됩니다.

+--------+
| 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);
Copy

출력에는 두 개의 열이 포함되며 두 번째 열에는 두 번째 테이블의 값 또는 NULL이 포함됩니다.

+------+------+
| UI_L | UI_R |
|------+------|
| a    | NULL |
+------+------+