SnowConvert: Oracle Select 문

선택

참고

출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.

전체 Select 변환

단순 select

입력 코드:
 select * from table1;
select col1 from schema1.table1;
Copy
출력 코드:
 select * from
table1;

select col1 from
schema1.table1;
Copy

Where 절

입력 코드:
 select col1 from schema1.table1 WHERE col1 = 1 and id > 0 or id < 1;
Copy
출력 코드:
 select col1 from
schema1.table1
WHERE col1 = 1 and id > 0 or id < 1;
Copy

Order By 절

입력 코드:
 select col1 from schema1.table1 order by id ASC;
Copy
출력 코드:
 select col1 from
schema1.table1
order by id ASC;
Copy

Group by

입력 코드:
 select col1 from schema1.table1 GROUP BY id;
Copy
출력 코드:
 select col1 from
schema1.table1
GROUP BY id;
Copy

Model 절

model 절은 아직 지원되지 않습니다.

Row Limiting 절

입력 코드:
 -- Using ONLY
select * from TableFetch1 FETCH FIRST 2 ROWS ONLY;
select * from TableFetch1 FETCH FIRST 20 percent ROWS ONLY;
select * from TableFetch1 order by col1 FETCH FIRST 2 ROWS with ties;
select * from TableFetch1 order by col1 FETCH FIRST 20 percent ROWS with ties;

-- Using OFFSET clause
select * from TableFetch1 offset 2 rows FETCH FIRST 2 ROWS ONLY;
select * from TableFetch1 offset 2 rows FETCH FIRST 60 percent rows ONLY;
select * from TableFetch1 
order by col1 offset 2 rows FETCH NEXT 2 ROWs with ties;
select * from TableFetch1 
order by col1 offset 2 rows FETCH FIRST 60 percent ROWs with ties;

-- Using WITH TIES clause
select * from TableFetch1 FETCH FIRST 2 ROWS with ties;
select * from TableFetch1 FETCH FIRST 20 percent ROWS with ties;
select * from TableFetch1 offset 2 rows FETCH NEXT 2 ROWs with ties;
select * from TableFetch1 offset 2 rows FETCH FIRST 60 percent ROWs with ties;

-- Using ORDER BY clause
select * from TableFetch1 order by col1 FETCH FIRST 2 ROWS ONLY;
select * from TableFetch1 order by col1 FETCH FIRST 20 percent ROWS ONLY;
select * from TableFetch1 order by col1 offset 2 rows FETCH FIRST 2 ROWS ONLY;
select * from TableFetch1 
order by col1 offset 2 rows FETCH FIRST 60 percent ROWS ONLY;

select * from TableFetch1 FETCH FIRST ROWS ONLY;

select * from TableFetch1 offset 2 rows;
Copy
출력 코드:
 -- Using ONLY
select * from
TableFetch1
FETCH FIRST 2 ROWS ONLY;

select * from
TableFetch1
QUALIFY
(ROW_NUMBER() OVER (
ORDER BY
NULL) - 1) / COUNT(*) OVER () < 20 / 100;

select * from
TableFetch1
QUALIFY
RANK() OVER (
order by col1) <= 2;

select * from
TableFetch1
QUALIFY
(RANK() OVER (
order by col1) - 1) / COUNT(*) OVER () < 20 / 100;

-- Using OFFSET clause
select * from
TableFetch1
offset 2 rows FETCH FIRST 2 ROWS ONLY;

select * from
TableFetch1
QUALIFY
(ROW_NUMBER() OVER (
ORDER BY
NULL) - 1 - 2) / COUNT(*) OVER () < 60 / 100
LIMIT NULL OFFSET 2;

select * from
TableFetch1
QUALIFY
RANK() OVER (
order by col1) - 2 <= 2
LIMIT NULL OFFSET 2;

select * from
TableFetch1
QUALIFY
(RANK() OVER (
order by col1) - 1 - 2) / COUNT(*) OVER () < 60 / 100
LIMIT NULL OFFSET 2;

-- Using WITH TIES clause
select * from
TableFetch1
FETCH FIRST 2 ROWS ONLY;

select * from
TableFetch1
QUALIFY
(ROW_NUMBER() OVER (
ORDER BY
NULL) - 1) / COUNT(*) OVER () < 20 / 100;

select * from
TableFetch1
offset 2 rows FETCH NEXT 2 ROWS ONLY;

select * from
TableFetch1
QUALIFY
(ROW_NUMBER() OVER (
ORDER BY
NULL) - 1 - 2) / COUNT(*) OVER () < 60 / 100
LIMIT NULL OFFSET 2;

-- Using ORDER BY clause
select * from
TableFetch1
order by col1
FETCH FIRST 2 ROWS ONLY;

select * from
TableFetch1
QUALIFY
(ROW_NUMBER() OVER (
order by col1) - 1) / COUNT(*) OVER () < 20 / 100;

select * from
TableFetch1
order by col1 offset 2 rows FETCH FIRST 2 ROWS ONLY;

select * from
TableFetch1
QUALIFY
(ROW_NUMBER() OVER (
order by col1) - 1 - 2) / COUNT(*) OVER () < 60 / 100
LIMIT NULL OFFSET 2;

select * from
TableFetch1
FETCH FIRST 1 ROWS ONLY;

select * from
TableFetch1
LIMIT NULL OFFSET 2;
Copy

참고

Oracle에서는SELECTORDER BY 가 지정되지 않은 경우 FETCH/OFFSET WITH TIES 가 무시됩니다. 이 경우 ONLY 키워드가 포함된 FETCH/OFFSET 으로 변환되고, Snowflake에서 ONLY 키워드는 결과에 영향을 미치지 않으며 가독성을 위해서만 사용됩니다.

피벗

Snowflake는 다음 문을 지원하지 않음:\ - 열 이름 바꾸기\ - 다중 열

입력 코드:

 select * from schema1.table1
PIVOT(count(*) as count1 FOR (column1, column2) IN (row1 as rowName));
Copy
출력 코드:
 select * from
schema1.table1
!!!RESOLVE EWI!!! /*** SSC-EWI-0015 - PIVOT/UNPIVOT RENAME COLUMN NOT SUPPORTED ***/!!!
PIVOT (count(*)
                !!!RESOLVE EWI!!! /*** SSC-EWI-0015 - PIVOT/UNPIVOT MULTIPLE COLUMN NOT SUPPORTED ***/!!!
                FOR (column1, column2)
!!!RESOLVE EWI!!! /*** SSC-EWI-0015 - PIVOT/UNPIVOT RENAME COLUMN NOT SUPPORTED ***/!!!
IN (row1 as rowName));
Copy

Unpivot

Snowflake는 다음 문을 지원하지 않음:\ - INCLUDE / EXCLUDE NULLS

입력 코드:

select * from schema1.table1 
UNPIVOT INCLUDE NULLS (column1 FOR column2 IN (ANY, ANY)); 
Copy
출력 코드:
 select * from
schema1.table1
!!!RESOLVE EWI!!! /*** SSC-EWI-0015 - PIVOT/UNPIVOT INCLUDE NULLS NOT SUPPORTED ***/!!!
UNPIVOT ( column1 FOR column2 IN (
ANY,
ANY));
Copy

JOIN (+)를 ANSI 구문으로 변환

이 변환은 현재 비활성화되어 있으며 이전 버전의 SnowConvert 로 수행한 변환에 대한 참조 용도로만 제공됩니다. 현재 변환은 위 섹션에서 확인하십시오.

SnowConvert 는 NON-ANSI 특수 외부 조인 (+) 구문을 ANSI 외부 조인 구문으로 변환합니다. 이 하위 섹션에서는 몇 가지 예를 보여줍니다.

LEFT OUTER JOIN 으로

예 1:
Input Code:
 -- Additional Params: --OuterJoinsToOnlyAnsiSyntax
SELECT d.department_name,
       e.employee_name      
FROM   departments d, employees e
WHERE  d.department_id = e.department_id (+) 
AND    d.department_id >= 30;
Copy
Output Code:
 SELECT d.department_name,
       e.employee_name
FROM
       departments d
       LEFT OUTER JOIN
              employees e
              ON d.department_id = e.department_id
WHERE
       d.department_id >= 30;
Copy
예 2:
Input Code:
 -- Additional Params: --OuterJoinsToOnlyAnsiSyntax
SELECT d.department_name,
       e.employee_name      
FROM   departments d, employees e
WHERE  d.department_id(+)  = e.department_id 
AND    d.department_id >= 30;
Copy
Output Code:
 SELECT d.department_name,
       e.employee_name
FROM
       employees e
       LEFT OUTER JOIN
              departments d
              ON d.department_id = e.department_id
WHERE
       d.department_id >= 30;
Copy

예 3: 다중 조인

Input Code:
 -- Additional Params: --OuterJoinsToOnlyAnsiSyntax
SELECT d.department_name,
       e.employee_name      
FROM   departments d, employees e, projects p
WHERE  e.department_id(+) = d.department_id
AND    p.department_id(+) = d.department_id
AND    d.department_id >= 30;
Copy
Output Code:
 SELECT d.department_name,
       e.employee_name
FROM
       departments d
       LEFT OUTER JOIN
              employees e
              ON e.department_id = d.department_id
       LEFT OUTER JOIN
              projects p
              ON p.department_id = d.department_id
WHERE
       d.department_id >= 30;
Copy

예 4: 다른 종류의 조건부와 조인하기

Input Code:
 -- Additional Params: --OuterJoinsToOnlyAnsiSyntax
SELECT d.department_name,
       e.employee_name      
FROM   departments d, employees e
WHERE  d.department_id(+)  = e.department_id 
AND    d.location(+) IN ('CHICAGO', 'BOSTON', 'NEW YORK')
AND    d.department_id >= 30;
Copy
Output Code:
 SELECT d.department_name,
       e.employee_name
FROM
       employees e
       LEFT OUTER JOIN
              departments d
              ON d.department_id = e.department_id
              AND d.location IN ('CHICAGO', 'BOSTON', 'NEW YORK')
WHERE
       d.department_id >= 30;
Copy

예 5: 함수 내에서 (+)로 조인하기

Input Code:
 -- Additional Params: --OuterJoinsToOnlyAnsiSyntax
SELECT d.department_name,
       e.employee_name
FROM   departments d, employees e
WHERE SUBSTR(d.department_name, 1, NVL(e.department_id, 1) ) = e.employee_name(+);
Copy
Output Code:
 SELECT d.department_name,
       e.employee_name
FROM
       departments d
       LEFT OUTER JOIN
              employees e
              ON SUBSTR(d.department_name, 1, NVL(e.department_id, 1) ) = e.employee_name;
Copy

경고

LEFT OUTER JOIN 으로 변환된 일부 패턴은 행을 다른 순서로 검색할 수 있다는 점에 유의하십시오.

CROSS JOIN 으로

예 6: CROSS JOIN 을 사용해야 하는 복잡한 경우

입력 코드:
-- Additional Params: --OuterJoinsToOnlyAnsiSyntax
SELECT d.department_name,
       e.employee_name,
       p.project_name,
       c.course_name 
FROM   departments d, employees e, projects p, courses c
WHERE
e.salary (+) >= 2000 AND
d.department_id = e.department_id (+)
AND p.department_id = e.department_id(+)
AND c.course_id  = e.department_id(+)
AND d.department_id >= 30;
Copy
출력 코드:
 SELECT d.department_name,
       e.employee_name,
       p.project_name,
       c.course_name
FROM
       departments d
       CROSS JOIN projects p
       CROSS JOIN courses c
       LEFT OUTER JOIN
              employees e
              ON
              e.salary >= 2000
              AND
              d.department_id = e.department_id
              AND p.department_id = e.department_id
              AND c.course_id  = e.department_id
WHERE
       d.department_id >= 30;
Copy

계층 쿼리

Snowflake의 계층적 쿼리는 일반적으로 CONNECT BY 절을 사용하여 트리와 같은 구조로 데이터를 조직하고 검색할 수 있습니다. 이 절은 테이블을 테이블 자체에 조인하여 테이블의 계층적 데이터를 처리합니다.

입력 코드:

 SELECT employee_ID, manager_ID, title
FROM employees
START WITH manager_ID = 1
CONNECT BY manager_ID = PRIOR employee_id;
Copy
출력 코드:
 SELECT employee_ID, manager_ID, title
FROM
employees
START WITH manager_ID = 1
CONNECT BY
manager_ID = PRIOR employee_id;
Copy

플래시백 쿼리 선택

select-flashback-query.md

플래시백 쿼리 선택

설명

Oracle

Oracle에서 플래시백 쿼리 절을 사용하면 테이블, 뷰 또는 구체화된 뷰에서 과거 데이터를 검색할 수 있습니다. Oracle에서는 다음과 같은 용도로 사용할 수 있습니다.

  • 삭제된 데이터 복원 또는 잘못된 커밋 실행 취소, 현재 데이터와 이전 시점의 해당 데이터 비교, 특정 시점의 트랜잭션 데이터 상태 확인, 과거 데이터에 대한 보고서 생성 도구 등을 사용할 수 있습니다. (Oracle 플래시백 쿼리 설명서).

Snowflake

과거 데이터를 쿼리하는 Snowflake의 동일한 메커니즘은 AT | BEGIN 쿼리입니다. 유일한 동등한 문은 AS OF 문입니다.

또한, Snowflake에는 데이터를 쿼리하여 테이블, 뷰, 스키마와 같은 오브젝트를 복제할 수 있는 완전한 “Time Travel” 설명서가 있습니다. 과거 또는 삭제된 데이터에 액세스할 수 있는 일수에는 제한이 있습니다(Fail-safe 상태로 넘어가기 전 90일). 자세한 내용은 Snowflake Time Travel 설명서 를 참조하십시오.

Oracle 구문

 { VERSIONS BETWEEN
  { SCN | TIMESTAMP }
  { expr | MINVALUE } AND { expr | MAXVALUE }
| AS OF { SCN | TIMESTAMP } expr
}
Copy

Snowflake 구문

 SELECT ...
FROM ...
  {
   AT( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> | STREAM => '<name>' } ) |
   BEFORE( STATEMENT => <id> )
  }
[ ... ]
Copy

참고

쿼리 ID 는 14일 이내에 실행된 쿼리를 참조해야 합니다. 쿼리 ID 가 14일이 지난 쿼리를 참조하는 경우 Error: statement <query_id> not found 오류가 반환됩니다. 이 제한을 해결하려면 참조된 쿼리에 타임스탬프를 사용하십시오. (Snowflake AT | Before 설명서)

샘플 소스 패턴

다음 예제에서는 쿼리 출력을 생성하는 데 다음 데이터가 사용됩니다.

 CREATE TABLE Employee (
    EmployeeID NUMBER PRIMARY KEY,
    FirstName VARCHAR2(50),
    LastName VARCHAR2(50),
    EmailAddress VARCHAR2(100),
    HireDate DATE,
    SalaryAmount NUMBER(10, 2)
);

INSERT INTO Employee VALUES (1, 'Bob', 'SampleNameA', 'sample@example.com', TO_DATE('2023-01-15', 'YYYY-MM-DD'), 11111.00);
INSERT INTO Employee VALUES (2, 'Bob', 'SampleNameB', 'sample@example.com', TO_DATE('2023-01-15', 'YYYY-MM-DD'), 11111.00);
INSERT INTO Employee VALUES (3, 'Bob', 'SampleNameC', 'sample@example.com', TO_DATE('2022-03-10', 'YYYY-MM-DD'), 11111.00);
INSERT INTO Employee VALUES (4, 'Bob', 'SampleNameD', 'sample@example.com', TO_DATE('2022-03-10', 'YYYY-MM-DD'), 11111.00);
INSERT INTO Employee VALUES (5, 'Bob', 'SampleNameE', 'sample@example.com', TO_DATE('2022-03-10', 'YYYY-MM-DD'), 11111.00);
Copy
 CREATE OR REPLACE TABLE Employee (
       EmployeeID NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/ PRIMARY KEY,
       FirstName VARCHAR(50),
       LastName VARCHAR(50),
       EmailAddress VARCHAR(100),
       HireDate TIMESTAMP /*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/,
       SalaryAmount NUMBER(10, 2) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/
   )
   COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
   ;

   INSERT INTO Employee
   VALUES (1, 'Bob', 'SampleNameA', 'sample@example.com', TO_DATE('2023-01-15', 'YYYY-MM-DD'), 11111.00);

   INSERT INTO Employee
   VALUES (2, 'Bob', 'SampleNameB', 'sample@example.com', TO_DATE('2023-01-15', 'YYYY-MM-DD'), 11111.00);

   INSERT INTO Employee
   VALUES (3, 'Bob', 'SampleNameC', 'sample@example.com', TO_DATE('2022-03-10', 'YYYY-MM-DD'), 11111.00);

   INSERT INTO Employee
   VALUES (4, 'Bob', 'SampleNameD', 'sample@example.com', TO_DATE('2022-03-10', 'YYYY-MM-DD'), 11111.00);

   INSERT INTO Employee
   VALUES (5, 'Bob', 'SampleNameE', 'sample@example.com', TO_DATE('2022-03-10', 'YYYY-MM-DD'), 11111.00);
Copy

1. AS OF with TIMESTAMP case

Oracle

 SELECT * FROM employees
AS OF TIMESTAMP
TO_TIMESTAMP('2023-09-27 07:00:00', 'YYYY-MM-DD HH:MI:SS')
WHERE last_name = 'SampleName';
Copy

Snowflake

 SELECT * FROM
employees
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0135 - DATA RETENTION PERIOD MAY PRODUCE NO RESULTS ***/!!!
AT (TIMESTAMP =>
TO_TIMESTAMP('2023-09-27 07:00:00', 'YYYY-MM-DD HH:MI:SS'))
WHERE last_name = 'SampleName';
Copy

2. AS OF with SCN case

Oracle

 SELECT * FROM employees
AS OF SCN
TO_TIMESTAMP('2023-09-27 07:00:00', 'YYYY-MM-DD HH:MI:SS')
WHERE last_name = 'SampleName';
Copy

Snowflake

 SELECT * FROM
employees
!!!RESOLVE EWI!!! /*** SSC-EWI-0040 - THE STATEMENT IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
AS OF SCN
TO_TIMESTAMP('2023-09-27 07:00:00', 'YYYY-MM-DD HH:MI:SS')
WHERE last_name = 'SampleName';
Copy

Known Issues

1. The option when it is using SCN is not supported.

2. The VERSION statement is not supported in Snowflake.

관련 EWIS

  1. SSC-EWI-0040: 문은 지원되지 않습니다.

  2. SSC-EWI-OR0135: 절의 Current는 Snowflake에서 지원되지 않습니다.

  3. SSC-FDM-0006: 숫자 유형 열은 Snowflake에서 유사하게 작동하지 않을 수 있습니다.

  4. SSC-FDM-OR0042: 타임스탬프로 변환된 날짜 유형은 동작이 다릅니다.