SnowConvert AI - ANSI SQL - 하위 쿼리¶
설명¶
하위 쿼리는 다른 쿼리 내의 쿼리입니다. FROM 또는 WHERE의 하위 쿼리 절은 포함하는 쿼리에서 반환되는 데이터를 제한하거나 비교/평가하는 데 사용할 데이터를 제공하는 데 사용됩니다.(Snowflake 하위 쿼리 설명서).
하위 쿼리는 스칼라 하위 쿼리/스칼라가 아닌 하위 쿼리뿐만 아니라 상관 관계가 있는 쿼리/상관 관계가 없는 쿼리가 될 수 있습니다.
상관 관계가 있는 하위 쿼리는 외부 쿼리의 열을 참조합니다. Snowflake에서 상관 관계가 있는 하위 쿼리는 쿼리의 각 행에 대해 실행됩니다. 반면, 상관 관계가 없는 하위 쿼리는 외부 쿼리를 참조하지 않으며 전체 쿼리에 대해 한 번 실행됩니다.
스칼라 하위 쿼리는 단일 값을 결과로 반환하며, 그렇지 않은 경우 해당 하위 쿼리는 스칼라가 아닌 하위 쿼리입니다.
다음 패턴은 이러한 카테고리를 기반으로 합니다.
샘플 소스 패턴¶
설정 데이터¶
Teradata¶
CREATE TABLE tableA
(
col1 INTEGER,
col2 VARCHAR(20)
);
CREATE TABLE tableB
(
col3 INTEGER,
col4 VARCHAR(20)
);
INSERT INTO tableA VALUES (50, 'Hey');
INSERT INTO tableA VALUES (20, 'Example');
INSERT INTO tableB VALUES (50, 'Hey');
INSERT INTO tableB VALUES (20, 'Bye');
Snowflake¶
CREATE OR REPLACE TABLE tableA
(
col1 INTEGER,
col2 VARCHAR(20)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "12/02/2024", "domain": "test" }}'
;
CREATE OR REPLACE TABLE tableB
(
col3 INTEGER,
col4 VARCHAR(20)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "12/02/2024", "domain": "test" }}'
;
INSERT INTO tableA
VALUES (50, 'Hey');
INSERT INTO tableA
VALUES (20, 'Example');
INSERT INTO tableB
VALUES (50, 'Hey');
INSERT INTO tableB
VALUES (20, 'Bye');
스칼라가 아닌 하위 쿼리¶
하위 쿼리 연산자 내부에 지정된 스칼라가 아닌 하위 쿼리(ANY/ALL/IN/EXISTS)가 지원됩니다.
파생 테이블로 사용되는 스칼라가 아닌 하위 쿼리도 지원됩니다.
Teradata¶
SELECT col2
FROM tableA
WHERE col1 IN (SELECT col3 FROM tableB);
SELECT col2
FROM tableA
WHERE col1 >= ALL(SELECT col3 FROM tableB);
SELECT col2, myDerivedTable.col4
FROM tableA, (SELECT * FROM tableB) AS myDerivedTable
WHERE col1 = myDerivedTable.col3;
결과¶
+---------+
| col2 |
+---------+
| Example |
+---------+
| Hey |
+---------+
+---------+
| col2 |
+---------+
| Hey |
+---------+
+---------+------+
| col2 | col4 |
+---------+------+
| Example | Bye |
+---------+------+
| Hey | Hey |
+---------+------+
Snowflake¶
SELECT
col2
FROM
tableA
WHERE col1 IN (
SELECT
col3 FROM
tableB
);
SELECT
col2
FROM
tableA
WHERE col1 >= ALL(
SELECT
col3 FROM
tableB
);
SELECT
col2,
myDerivedTable.col4
FROM
tableA, (
SELECT
* FROM
tableB
) AS myDerivedTable
WHERE col1 = myDerivedTable.col3;
결과¶
+---------+
| col2 |
+---------+
| Example |
+---------+
| Hey |
+---------+
+---------+
| col2 |
+---------+
| Hey |
+---------+
+---------+------+
| col2 | col4 |
+---------+------+
| Example | Bye |
+---------+------+
| Hey | Hey |
+---------+------+
Known Issues¶
**1. 상관 관계가 없는 스칼라가 아닌 FETCH를 먼저 사용하는 하위 쿼리
Oracle은 하위 쿼리에서 FETCH 절의 사용을 허용하지만, Snowflake는 하위 쿼리가 상관 관계가 없는 스칼라 하위 쿼리인 경우에만 이 절을 사용할 수 있도록 허용합니다. 그렇지 않은 경우에는 예외가 생성됩니다.
SnowConvert AI는 하위 쿼리에서 FETCH를 잘못 사용하는 경우 SSC-EWI-0108로 표시합니다.
Oracle:
-- Correlated scalar
SELECT col2
FROM tableA
WHERE col2 = (SELECT col4 FROM tableB WHERE col3 = col1 FETCH FIRST ROW ONLY);
-- Uncorrelated scalar
SELECT col2
FROM tableA
WHERE col2 = (SELECT col4 FROM tableB FETCH FIRST ROW ONLY);
Snowflake:
-- Correlated scalar
SELECT col2
FROM
tableA
WHERE col2 =
--** SSC-FDM-0002 - CORRELATED SUBQUERIES MAY HAVE SOME FUNCTIONAL DIFFERENCES. **
!!!RESOLVE EWI!!! /*** SSC-EWI-0108 - THE FOLLOWING SUBQUERY MATCHES AT LEAST ONE OF THE PATTERNS CONSIDERED INVALID AND MAY PRODUCE COMPILATION ERRORS ***/!!! (SELECT
ANY_VALUE( col4) FROM
tableB
WHERE col3 = col1
FETCH FIRST 1 ROW ONLY);
-- Uncorrelated scalar
SELECT col2
FROM
tableA
WHERE col2 = (SELECT col4 FROM
tableB
FETCH FIRST 1 ROW ONLY);