LoginSignup
1
0

Snowflakeで複数のLISTやSHOW結果をSELECTでまとめて表示したい時

Last updated at Posted at 2024-04-28

概要

LISTとかSHOWってちょっと不便な関数で、呼び出しと同時にSELECTにかける事ができず

源泉が複数あり、源泉ごとにステージがある場合
それぞれのステージごとにファイルの状況をみようとおもったら

  • それぞれのステージを対象にLISTって打つ
  • RESULT_SCAN経由でSELECT〜でステージ単位の集計を見る
  • 別のステージ対象にして繰り返し…

と考えるだけでものすごくめんどくさくなってくるので
以下のサンプルを元に、集計してくるクエリを考えようと思います

サンプルデータ

TEST_DB
  └ TEST
      ├ TEST_STAGE
      │     ├ hoge_202404252050.csv
      │     └ hoge_202404282050.csv
      └ TEST2_STAGE
             ├ fuga_202404272050.csv
             └ fuga_202404282050.csv

こんな感じでステージごとにファイル名にデータ日付がある場合
例えばステージのファイル種別ごとの更新日とか1回で取りたいですよね?

と、いうことで…

各ステージのファイル種別(分割した上で左側をファイル種別とする)ごとの最終ファイル名と最終更新時刻を取るクエリ

SQL
DECLARE
    QUERIES ARRAY DEFAULT [];
BEGIN
    LET STG_RESULT RESULTSET := (SELECT STAGE_NAME,STAGE_SCHEMA FROM INFORMATION_SCHEMA.STAGES );
    LET STG_CUR CURSOR FOR STG_RESULT;
    
    FOR STG IN STG_CUR DO
        LET STG_NAME TEXT := STG.STAGE_NAME;
        LET STG_SCHEMA TEXT := STG.STAGE_SCHEMA;
        EXECUTE IMMEDIATE ('LIST @'|| :STG_SCHEMA || '.'|| :STG_NAME );
        QUERIES := ARRAY_APPEND(QUERIES,LAST_QUERY_ID());
    END FOR;
    
    LET Q_RS RESULTSET := (SELECT VALUE FROM TABLE(FLATTEN( INPUT => :QUERIES)));
    LET Q_CUR CURSOR FOR Q_RS;

    LET GET_LIST_QUERY TEXT := '';

    FOR QID IN Q_CUR DO
        LET Q TEXT := QID.VALUE;
        IF (GET_LIST_QUERY != '') THEN
            GET_LIST_QUERY := GET_LIST_QUERY || '\n UNION ALL \n';
        END IF;

        GET_LIST_QUERY := GET_LIST_QUERY || 'SELECT
            SPLIT_PART($1,''/'',-2) AS STAGE ,
            SPLIT_PART(SPLIT_PART($1,''/'',-1),''_'',1) AS FILE_TYPE, 
            MAX(TRY_TO_TIMESTAMP(SPLIT_PART(SPLIT_PART(SPLIT_PART($1,''/'',-1),''_'',2),''.'',1),''YYYYMMDDHH24MI'')) AS FILE_DATE,
            MAX_BY($4,TRY_TO_TIMESTAMP(SPLIT_PART(SPLIT_PART(SPLIT_PART($1,''/'',-1),''_'',2),''.'',1),''YYYYMMDDHH24MI'')) AS LAST_MODIFIED
            FROM TABLE(RESULT_SCAN(''' || :Q || ''')) GROUP BY 1,2';
    END FOR;
    LET RS RESULTSET := (EXECUTE IMMEDIATE :GET_LIST_QUERY);
    RETURN TABLE(RS);
END;

ちょーっと後半が奇怪な処理になってしまっていますが…

実行結果

スクリーンショット 2024-04-28 21.33.56.png

複数ステージの最大日付とファイル日付、最終更新日が取れました (∩´∀`)∩

ちょっとした説明

LISTの結果を加工する場合はRESULT_SCANを通してからSELECTするしかないのですが
上にも書いたように、RESULT_SCANに渡せるのはQUERY_ID、そして実行ごとにクエリIDを取るのはものすごいめんどくさい

のでちょっと力こそパワーで解決するべく下記の感じで処理を行っています。

  • INFOMATION_SCHEMAからステージをGET
  • LISTを実行
  • LAST_QUERY_IDを使い、LISTが実行された時のクエリIDを取得
  • 取得したクエリIDを行に戻す
  • RESULT_SCANごとに集計
  • 集計結果をUNION ALL…

SHOWとかLISTがもうちょい加工しやすくなればこんな処理はいらないんですが… (´・ω・`)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0