카테고리:

테이블 함수

RESULT_SCAN

결과가 테이블인 것처럼 이전 명령의 결과 세트(쿼리를 실행한 후 24시간 이내)를 반환합니다. 이 함수는 다음 작업의 출력을 처리하려는 경우에 특히 유용합니다.

명령 또는 쿼리는 24시간이 경과하지 않는 한, 현재 세션 또는 과거 세션을 포함한 다른 세션에서 가져올 수 있습니다. 이 기간은 조정할 수 없습니다. 자세한 내용은 지속형 쿼리 결과 사용하기 섹션을 참조하세요.

이 함수 대신 파이프 연산자 (->>)를 사용하여 이전 명령의 결과를 처리할 수 있습니다.

참고 항목:

DESCRIBE RESULT (계정 및 세션 DDL)

구문

RESULT_SCAN ( [ { '<query_id>' | <query_index>  | LAST_QUERY_ID() } ] )
Copy

인자

'query_id' 또는 query_index 또는 LAST_QUERY_ID()

최근 24시간 내에 세션에서 실행한 쿼리의 사양, 현재 세션에서 쿼리의 정수 인덱스 또는 현재 세션 내에서 쿼리의 LAST_QUERY_ID 를 반환하는 ID 함수입니다.

Snowflake 쿼리 ID는 01b71944-0001-b181-0000-0129032279f6 과 비슷한 고유한 문자열입니다.

쿼리 인덱스는 현재 세션의 첫 번째 쿼리(양수인 경우) 또는 가장 최근 쿼리(음수인 경우)를 기준으로 합니다. 예를 들어 RESULT_SCAN(-1)RESULT_SCAN(LAST_QUERY_ID()) 와 같습니다.

이 인자는 선택 사항입니다. 생략하면 기본값은 가장 최근 명령의 결과 세트를 반환하는 RESULT_SCAN(-1) 입니다.

사용법 노트

  • 원래 쿼리를 수동으로 실행한 경우 원래 쿼리를 실행한 사용자만 RESULT_SCAN 함수를 사용하여 쿼리의 출력을 처리할 수 있습니다. ACCOUNTADMIN 권한이 있는 사용자도 RESULT_SCAN을 호출하여 다른 사용자의 쿼리 결과에 액세스할 수 없습니다.

  • 작업 을 사용하여 원래 쿼리를 실행한 경우 특정 사용자 대신 작업을 소유한 역할이 쿼리를 트리거하고 실행했습니다. 사용자 또는 작업이 동일한 역할로 작업하는 경우 RESULT_SCAN을 사용하여 쿼리 결과에 액세스할 수 있습니다.

  • Snowflake는 모든 쿼리 결과를 24시간 동안 저장합니다. 이 함수는 이 기간 내에 실행된 쿼리에 대한 결과만 반환합니다.

  • 결과 세트에는 연결된 메타데이터가 없으므로 큰 결과를 처리하는 속도는 실제 테이블을 쿼리하는 경우보다 느릴 수 있습니다.

  • RESULT_SCAN이 포함된 쿼리는 필터 및 원래 쿼리에 없는 ORDER BY 절과 같은 절을 포함할 수 있습니다. 이러한 절을 사용하여 결과 세트의 범위를 좁히거나 수정할 수 있습니다.

  • RESULT_SCAN은 원래 쿼리가 행을 반환한 것과 동일한 순서로 행을 반환한다고 보장되지 않습니다. RESULT_SCAN 쿼리에 ORDER BY 절을 포함하여 특정 순서를 지정할 수 있습니다.

  • 특정 쿼리의 ID를 검색하려면 다음 방법 중 하나를 사용하십시오.

    Snowsight:

    다음 위치 중 하나에서, 제공된 링크를 클릭하여 ID를 표시하거나 복사합니다.

    • Projects 아래의 Worksheets 에서 쿼리를 실행한 후 Query Details 에는 ID에 대한 링크가 포함됩니다.

    • Monitoring 아래의 Query History 에서 각 쿼리는 ID를 링크로 포함합니다.

    SQL:

    다음 함수 중 하나를 호출합니다.

  • RESULT_SCAN이 중복 열 이름이 포함된 쿼리 출력(예: 겹치는 열 이름이 있는 두 테이블을 조인한 쿼리)을 처리하는 경우, RESULT_SCAN은 수정된 이름을 사용하여 중복 열을 참조하고 원래 이름에 _1, _2 등을 추가합니다. 예제에 대해서는 다음 예제 섹션을 참조하세요.

  • 벡터화된 스캐너를 사용하여 쿼리하는 Parquet 파일의 타임스탬프에 다른 타임존의 시간이 표시되는 경우가 있습니다. CONVERT_TIMEZONE 함수를 사용하여 모든 타임스탬프 데이터에 대해 표준 타임존으로 변환합니다.

데이터 정렬 세부 정보

RESULT_SCAN 이 이전 문의 결과를 반환할 때 RESULT_SCAN 은 반환하는 값의 데이터 정렬 사양을 유지합니다.

다음 예제에서는 RESULT_SCAN 함수를 사용합니다.

간단한 예제

다음과 같이 현재 세션의 가장 최근 쿼리 결과에서 1 보다 큰 모든 값을 검색합니다.

SELECT $1 AS value FROM VALUES (1), (2), (3);
Copy
+-------+
| VALUE |
|-------|
|     1 |
|     2 |
|     3 |
+-------+
SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) WHERE value > 1;
Copy
+-------+
| VALUE |
|-------|
|     2 |
|     3 |
+-------+

다음과 같이 현재 세션에서 두 번째로 최근인 쿼리에서 모든 값을 검색합니다.

SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID(-2)));
Copy

다음과 같이 현재 세션의 첫 번째 쿼리에서 모든 값을 검색합니다.

SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID(1)));
Copy

다음과 같이 지정된 쿼리 결과의 c2 열에서 값을 검색합니다.

SELECT c2 FROM TABLE(RESULT_SCAN('ce6687a4-331b-4a57-a061-02b2b0f0c17c'));
Copy

DESCRIBE 및 SHOW 명령을 사용한 예

DESCRIBE USER 명령의 결과를 처리하여 사용자의 기본 역할과 같이 관심 있는 특정 필드를 검색합니다. DESC USER 명령의 출력 열 이름이 소문자로 생성된 경우 명령은 쿼리의 열 이름에 큰따옴표로 묶인 식별자 를 사용하여 쿼리의 열 이름이 스캔된 출력의 열 이름과 일치하도록 합니다.

DESC USER jessicajones;
SELECT "property", "value" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
  WHERE "property" = 'DEFAULT_ROLE';
Copy

SHOW TABLES 명령의 결과를 처리하여 21일보다 오래된 빈 테이블을 추출합니다. SHOW 명령은 소문자 열 이름을 생성하므로 이 명령은 일치하는 대소문자를 사용하도록 이름에 따옴표를 사용합니다.

SHOW TABLES;
SELECT "database_name", "schema_name", "name" as "table_name", "rows", "created_on"
  FROM table(RESULT_SCAN(LAST_QUERY_ID()))
  WHERE "rows" = 0 AND "created_on" < DATEADD(day, -21, CURRENT_TIMESTAMP())
  ORDER BY "created_on";
Copy

SHOW TABLES 명령의 결과를 처리하여 테이블을 크기의 내림차순으로 추출합니다. 또한 다음 예제에서는 UDF를 사용하여 테이블 크기를 사람이 좀 더 읽기 쉬운 형식으로 표시합니다.

-- Show byte counts with suffixes such as "KB", "MB", and "GB".
CREATE OR REPLACE FUNCTION NiceBytes(NUMBER_OF_BYTES INTEGER)
RETURNS VARCHAR
AS
$$
CASE
  WHEN NUMBER_OF_BYTES < 1024
    THEN NUMBER_OF_BYTES::VARCHAR
  WHEN NUMBER_OF_BYTES >= 1024 AND NUMBER_OF_BYTES < 1048576
    THEN (NUMBER_OF_BYTES / 1024)::VARCHAR || 'KB'
  WHEN NUMBER_OF_BYTES >= 1048576 AND NUMBER_OF_BYTES < (POW(2, 30))
    THEN (NUMBER_OF_BYTES / 1048576)::VARCHAR || 'MB'
  ELSE
    (NUMBER_OF_BYTES / POW(2, 30))::VARCHAR || 'GB'
END
$$
;
SHOW TABLES;
-- Show all of my tables in descending order of size.
SELECT "database_name", "schema_name", "name" as "table_name", NiceBytes("bytes") AS "size"
  FROM table(RESULT_SCAN(LAST_QUERY_ID()))
  ORDER BY "bytes" DESC;
Copy

저장 프로시저를 사용한 예

저장 프로시저 호출은 값을 반환합니다. 그러나 다른 문에 저장 프로시저 호출을 포함할 수 없으므로 이 값을 직접 처리할 수 없습니다. 이 제한을 해결하기 위해 RESULT_SCAN을 사용하여 저장 프로시저에서 반환된 값을 처리할 수 있습니다. 단순화된 예는 다음과 같습니다.

먼저, JSON 에서 반환된 후 처리할 수 있는 “복잡한” 값(이 경우, CALL 호환 데이터가 포함된 문자열)을 반환하는 프로시저를 만듭니다.

CREATE OR REPLACE PROCEDURE return_json()
  RETURNS VARCHAR
  LANGUAGE JavaScript
  AS
  $$
    return '{"keyA": "ValueA", "keyB": "ValueB"}';
  $$
  ;
Copy

프로시저를 호출합니다.

CALL return_json();
Copy
+--------------------------------------+
| RETURN_JSON                          |
|--------------------------------------|
| {"keyA": "ValueA", "keyB": "ValueB"} |
+--------------------------------------+

다음 세 단계는 결과 세트에서 데이터를 추출합니다.

다음과 같이 첫 번째(그리고 유일한) 열을 가져옵니다.

SELECT $1 AS output_col FROM table(RESULT_SCAN(LAST_QUERY_ID()));
Copy
+--------------------------------------+
| OUTPUT_COL                           |
|--------------------------------------|
| {"keyA": "ValueA", "keyB": "ValueB"} |
+--------------------------------------+

VARCHAR 값의 출력을 VARIANT 값으로 변환합니다.

SELECT PARSE_JSON(output_col) AS json_col FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()));
Copy
+---------------------+
| JSON_COL            |
|---------------------|
| {                   |
|   "keyA": "ValueA", |
|   "keyB": "ValueB"  |
| }                   |
+---------------------+

다음과 같이 키 keyB 에 해당하는 값을 추출합니다.

SELECT json_col:keyB FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()));
Copy
+---------------+
| JSON_COL:KEYB |
|---------------|
| "ValueB"      |
+---------------+

다음 예제에서는 이전 예제에서 추출한 것과 동일한 데이터를 추출하는 더 간결한 방법을 보여줍니다. 이 예제는 더 적은 수의 문을 사용하지만 읽기가 더 어렵습니다.

CALL return_json();
Copy
+--------------------------------------+
| RETURN_JSON                          |
|--------------------------------------|
| {"keyA": "ValueA", "keyB": "ValueB"} |
+--------------------------------------+
SELECT JSON_COL:keyB
 FROM (
      SELECT PARSE_JSON($1::VARIANT) AS json_col
        FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
      );
Copy
+---------------+
| JSON_COL:KEYB |
|---------------|
| "ValueB"      |
+---------------+

CALL의 출력은 함수 이름을 열 이름으로 사용합니다. 쿼리에서 해당 열 이름을 사용할 수 있습니다. 다음 예제는 열이 열 번호 대신 이름으로 참조되는 추가 압축 버전을 보여줍니다.

CALL return_json();
Copy
+--------------------------------------+
| RETURN_JSON                          |
|--------------------------------------|
| {"keyA": "ValueA", "keyB": "ValueB"} |
+--------------------------------------+
SELECT json_col:keyB
  FROM (
       SELECT PARSE_JSON(RETURN_JSON::VARIANT) AS json_col
         FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
       );
Copy
+---------------+
| JSON_COL:KEYB |
|---------------|
| "ValueB"      |
+---------------+

중복 열 이름을 갖는 예

다음 예에서는 원래 쿼리에 중복 열 이름이 있는 경우 RESULT_SCAN이 대체 열 이름을 효과적으로 참조함을 보여줍니다.

이름이 같은 열이 하나 이상 있는 두 개의 테이블을 다음과 같이 만듭니다.

CREATE TABLE employees (id INT);

CREATE TABLE dependents (id INT, employee_id INT);
Copy

다음과 같이 이 두 테이블에 데이터를 로딩합니다.

INSERT INTO employees (id) VALUES (11);

INSERT INTO dependents (id, employee_id) VALUES (101, 11);
Copy

이제 동일한 이름을 가진 두 개의 열이 출력에 포함될 쿼리를 다음과 같이 실행합니다.

SELECT *
  FROM employees INNER JOIN dependents
    ON dependents.employee_ID = employees.id
  ORDER BY employees.id, dependents.id;
Copy
+----+-----+-------------+
| ID |  ID | EMPLOYEE_ID |
|----+-----+-------------|
| 11 | 101 |          11 |
+----+-----+-------------+

이제 RESULT_SCAN을 호출하여 해당 쿼리의 결과를 처리합니다. 결과에 같은 이름을 가진 다른 열이 있는 경우, RESULT_SCAN은 첫 번째 열에 원래 이름을 사용하고 두 번째 열에 고유한 수정된 이름을 할당합니다. 이름을 고유하게 만들기 위해 RESULT_SCAN은 이름에 접미사 _n 을 추가합니다. 여기서 n 은 이전 열의 이름과 다른 이름을 생성하기 위해 사용 가능한 다음 번호입니다.

SELECT id, id_1, employee_id
  FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
  WHERE id_1 = 101;
Copy
+----+------+-------------+
| ID | ID_1 | EMPLOYEE_ID |
|----+------+-------------|
| 11 |  101 |          11 |
+----+------+-------------+