- 카테고리:
RESULT_SCAN¶
결과가 테이블인 것처럼 이전 명령의 결과 세트(쿼리를 실행한 후 24시간 이내)를 반환합니다. 이는 다음 중 하나의 출력을 처리하려는 경우에 특히 유용합니다.
실행한 SHOW 또는 DESC[RIBE] 명령.
Snowflake Information Schema 또는 Account Usage 과 같은 메타데이터 또는 계정 사용 정보에 대해 실행한 쿼리.
호출한 저장 프로시저의 결과.
명령/쿼리는 24시간이 경과하지 않는 한, 현재 세션 또는 과거 세션 등 다른 세션에서 가져올 수 있습니다. 이 기간은 조정할 수 없습니다. 자세한 내용은 지속형 쿼리 결과 사용하기 섹션을 참조하십시오.
- 참고 항목:
DESCRIBE RESULT (계정 및 세션 DDL)
구문¶
RESULT_SCAN ( { '<query_id>' | LAST_QUERY_ID() } )
인자¶
query_id
또는LAST_QUERY_ID()
(모든 세션에서 지난 24시간 이내에) 실행한 쿼리의 ID 또는 LAST_QUERY_ID 함수로, 이 함수는 현재 세션 내 쿼리의 ID를 반환합니다.
사용법 노트¶
원본 쿼리를 수동으로 실행하는 경우 원본 쿼리를 실행하는 사용자만 RESULT_SCAN 함수를 사용하여 쿼리 출력을 처리할 수 있습니다. ACCOUNTADMIN 권한을 가진 사용자라도 RESULT_SCAN을 호출하여 다른 사용자의 쿼리 결과에 액세스할 수 없습니다.
원본 쿼리가 작업 을 통해 실행되는 경우 특정 사용자 대신 작업을 소유한 역할이 쿼리를 트리거하고 실행합니다. 사용자 또는 작업이 동일한 역할로 작업하는 경우 RESULT_SCAN을 사용하여 쿼리 결과에 액세스할 수 있습니다.
Snowflake는 모든 쿼리 결과를 24시간 동안 저장합니다. 이 함수는 이 기간 내에 실행된 쿼리에 대한 결과만 반환합니다.
결과 세트에는 연결된 메타데이터가 없으므로 큰 결과를 처리하는 속도는 실제 테이블을 쿼리하는 경우보다 느릴 수 있습니다.
RESULT_SCAN을 포함하는 쿼리에는 원래 쿼리에 없던 필터 및 ORDER BY 절 등의 절이 포함될 수 있습니다. 이렇게 하면 결과 세트를 좁히거나 수정할 수 있습니다.
RESULT_SCAN은 원래 쿼리에서 행을 반환한 것과 같은 순서로 행을 반환하는 것으로 보장되지 않습니다. 특정 순서를 지정하기 위해 RESULT_SCAN 쿼리와 함께 ORDER BY 절을 포함할 수 있습니다.
특정 쿼리의 ID를 검색하려면 다음 방법 중 하나를 사용하십시오.
- Classic Console:
다음 위치 중 하나에서, 제공된 링크를 클릭하여 ID를 표시/복사합니다.
- SQL:
다음 함수 중 하나를 실행합니다.
LAST_QUERY_ID 함수(쿼리가 현재 세션에서 실행된 경우).
예:
SELECT LAST_QUERY_ID(-2);
이는 RESULT_SCAN에 대한 입력으로 LAST_QUERY_ID 를 사용하는 것과 동일합니다.
RESULT_SCAN이 중복 열 이름이 포함된 쿼리 출력(예: 겹치는 열 이름이 있는 두 테이블을 조인한 쿼리)을 처리하는 경우, RESULT_SCAN은 수정된 이름을 사용하여 중복 열을 참조하고 원래 이름에 “_1”, “_2” 등을 추가합니다. 예를 보려면 아래의 예 섹션을 참조하십시오.
벡터화된 스캐너를 사용하여 쿼리된 Parquet 파일의 타임스탬프는 때때로 다른 타임존으로 시간을 표시합니다. 모든 타임스탬프 데이터에 대해 CONVERT_TIMEZONE 함수를 사용하여 표준 타임존으로 변환합니다.
데이터 정렬 세부 정보¶
RESULT_SCAN
이 이전 문의 결과를 반환할 때 RESULT_SCAN
은 반환하는 값의 데이터 정렬 사양을 유지합니다.
예¶
간단한 예¶
다음과 같이 현재 세션의 가장 최근 쿼리 결과에서 1
보다 큰 모든 값을 검색합니다.
SELECT $1 AS value FROM VALUES (1), (2), (3); +-------+ | VALUE | |-------| | 1 | | 2 | | 3 | +-------+ SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) WHERE value > 1; +-------+ | VALUE | |-------| | 2 | | 3 | +-------+
다음과 같이 현재 세션에서 두 번째로 최근인 쿼리에서 모든 값을 검색합니다.
SELECT * FROM table(RESULT_SCAN(LAST_QUERY_ID(-2)));
다음과 같이 현재 세션의 첫 번째 쿼리에서 모든 값을 검색합니다.
SELECT * FROM table(RESULT_SCAN(LAST_QUERY_ID(1)));
다음과 같이 지정된 쿼리 결과의 c2
열에서 값을 검색합니다.
SELECT c2 FROM TABLE(RESULT_SCAN('ce6687a4-331b-4a57-a061-02b2b0f0c17c'));
DESCRIBE 및 SHOW 명령을 사용한 예¶
DESCRIBE USER 명령의 결과를 처리하여, 관심 있는 특정 필드(예: 사용자의 기본 역할)를 검색합니다. DESC USER
명령의 출력 열 이름이 소문자로 생성되었기 때문에 명령은 쿼리의 열 이름이 검색된 출력의 열 이름과 일치하도록 쿼리의 열 이름 주위에 구분 식별자 표기법(큰따옴표)을 사용합니다.
DESC USER jessicajones; SELECT "property", "value" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) WHERE "property" = 'DEFAULT_ROLE' ;
SHOW TABLES 명령의 결과를 처리하여 21일보다 오래된 빈 테이블을 추출합니다. SHOW 명령은 소문자 열 이름을 생성하므로, 이 명령은 이름을 따옴표로 묶고 일치하는 대/소문자를 사용합니다.
SHOW TABLES; -- Show the tables that are more than 21 days old and that are empty -- (i.e. tables that I might have forgotten about). 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";
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;
저장 프로시저를 사용한 예¶
저장 프로시저 호출은 값을 반환합니다. 그러나 다른 문에 저장 프로시저 호출을 포함할 수 없기 때문에 이 값은 직접 처리될 수 없습니다. 이 제한을 해결하기 위해 RESULT_SCAN
을 사용하여 저장 프로시저에서 반환된 값을 처리할 수 있습니다. 단순화된 예는 다음과 같습니다.
먼저,
CALL
에서 반환된 후 처리할 수 있는 “복잡한” 값(이 경우, JSON 호환 데이터가 포함된 문자열)을 반환하는 프로시저를 만듭니다.CREATE OR REPLACE PROCEDURE return_JSON() RETURNS VARCHAR LANGUAGE JavaScript AS $$ return '{"keyA": "ValueA", "keyB": "ValueB"}'; $$ ;둘째, 다음과 같이 프로시저를 호출합니다.
CALL return_JSON(); +--------------------------------------+ | RETURN_JSON | |--------------------------------------| | {"keyA": "ValueA", "keyB": "ValueB"} | +--------------------------------------+다음 세 단계는 결과 세트에서 데이터를 추출합니다.
다음과 같이 첫 번째(그리고 유일한) 열을 가져옵니다.
SELECT $1 AS output_col FROM table(RESULT_SCAN(LAST_QUERY_ID())); +--------------------------------------+ | OUTPUT_COL | |--------------------------------------| | {"keyA": "ValueA", "keyB": "ValueB"} | +--------------------------------------+다음과 같이 VARCHAR의 출력을 VARIANT로 변환합니다.
SELECT PARSE_JSON(output_col) AS JSON_COL FROM table(RESULT_SCAN(LAST_QUERY_ID())); +---------------------+ | JSON_COL | |---------------------| | { | | "keyA": "ValueA", | | "keyB": "ValueB" | | } | +---------------------+다음과 같이 키 “keyB”에 해당하는 값을 추출합니다.
SELECT JSON_COL:keyB FROM table(RESULT_SCAN(LAST_QUERY_ID())); +---------------+ | JSON_COL:KEYB | |---------------| | "ValueB" | +---------------+
다음은 이전 예에서 추출한 것과 동일한 데이터를 추출하는 더 간결한 방법입니다. 이 예에는 문이 더 적지만, 읽기가 더 어렵습니다.
CALL return_JSON(); +--------------------------------------+ | 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())) ); +---------------+ | JSON_COL:KEYB | |---------------| | "ValueB" | +---------------+
CALL의 출력은 함수 이름을 열 이름으로 사용합니다. 예:
+--------------------------------------+ | RETURN_JSON | +--------------------------------------+ | {"keyA": "ValueA", "keyB": "ValueB"} | +--------------------------------------+
쿼리에서 해당 열 이름을 사용할 수 있습니다. 다음은 열이 열 번호가 아닌 이름으로 참조되는 추가적인 간결한 버전입니다.
CALL return_JSON(); +--------------------------------------+ | 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())) ); +---------------+ | JSON_COL:KEYB | |---------------| | "ValueB" | +---------------+
중복 열 이름이 있는 예¶
다음 예에서는 원래 쿼리에 중복 열 이름이 있는 경우 RESULT_SCAN이 대체 열 이름을 효과적으로 참조함을 보여줍니다.
이름이 같은 열이 하나 이상 있는 두 개의 테이블을 다음과 같이 만듭니다.
CREATE TABLE employees (id INT);CREATE TABLE dependents (id INT, employee_id INT);다음과 같이 이 두 테이블에 데이터를 로딩합니다.
INSERT INTO employees (id) VALUES (11);INSERT INTO dependents (id, employee_id) VALUES (101, 11);이제 동일한 이름을 가진 두 개의 열이 출력에 포함될 쿼리를 다음과 같이 실행합니다.
SELECT * FROM employees INNER JOIN dependents ON dependents.employee_ID = employees.id ORDER BY employees.id, dependents.id ; +----+-----+-------------+ | ID | ID | EMPLOYEE_ID | |----+-----+-------------| | 11 | 101 | 11 | +----+-----+-------------+Snowsight 는 중복 열 이름을 자동으로 처리하므로 Snowsight 의 출력은 위에 표시된 출력과는 다릅니다.
이제 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; +----+------+-------------+ | ID | ID_1 | EMPLOYEE_ID | |----+------+-------------| | 11 | 101 | 11 | +----+------+-------------+