簡體   English   中英

bigquery sql 表 function 帶字符串插值

[英]bigquery sql table function with string interpolation

我正在嘗試編寫接受輸入的 BigQuery SQL function/存儲過程/表 function:

  • WHERE子句的INT64過濾器,
  • 表名( STRING類型)作為完全限定名稱,例如project_id.dataset_name.table_name

這個想法是動態地找出表名並提供一個過濾器來分割數據以作為表返回。

但是,如果嘗試編寫表 Function (TVF) 並且我使用SET開始動態編寫 SQL 來執行,那么我會看到此錯誤:

Syntax error: Expected "(" or keyword SELECT or keyword WITH but got keyword SET at [4:5]

如果我嘗試編寫一個存儲過程,那么它需要BEGINEND並拋出此錯誤:

Syntax error: Expected keyword BEGIN or keyword LANGUAGE but got keyword AS at [3:1]

如果我嘗試添加這些,那么我會收到各種驗證錯誤,主要是因為我需要使用 CTE(公用表表達式)和分號刪除WITH ; 等等

但我真正想做的是使用表 function

  1. 將一些 CTE 與上面的輸入動態組合(例如輸入表名稱),
  2. PIVOT那個數據,
  3. 然后最終返回一個表作為SELECT的結果。

有點像生成一個可以在其他 SQL 查詢中使用的視圖,但不創建視圖(因為可以使用其他INT64輸入過濾器動態決定數據切片)。

動態構建 SQL 字符串后,我想EXECUTE IMMEDIATE該 SQL 並提供SELECT作為表 function 的最后一步以返回“動態表”。

問題是:

  • 我在運行前不知道這張表的名字。
  • 但是我有所有這些具有相同結構的表,所以 SQL 應該適用於所有這些表。

這可能嗎?

這是我正在嘗試解決的不太工作的 SQL。 看看我試圖用%snum_days注入什么:

CREATE OR REPLACE TABLE FUNCTION `my_dataset.my_table_func_name`(num_days INT64, fqn_org_table STRING)
AS (
    -- this SET breaks !!!

    SET f_query = """
    WITH report_cst_t AS (
        SELECT
            DATE(start) as day,
            entity_id,
            conn_sub_type,
        FROM `%s` AS oa
        CROSS JOIN UNNEST(oa.connection_sub_type) AS conn_sub_type
        WHERE
            DATE(start) > DATE_SUB(CURRENT_DATE(), INTERVAL num_days DAY)
            AND oa.entity_id IN ('my-very-long-id')
        ORDER BY 1, 2 ASC
    ),
    cst AS (
        SELECT * FROM
            (SELECT day, entity_id, report_cst_t FROM report_cst_t)
            PIVOT (COUNT(*) AS connection_sub_type FOR report_cst_t.conn_sub_type IN ('cat1', 'cat2','cat3' ))
    )
    """;

    -- here I would like to EXECUTE IMMEDIATE !!!

    SELECT
            cst.day,
            cst.entity_id,
            cst.connection_sub_type_cat1 AS cst_cat1,
            cst.connection_sub_type_cat2 AS cst_cat2,
            cst.connection_sub_type_cat3 AS cst_cat3,
    FROM cst
    ORDER BY 1, 2 ASC
);

這可能並不令人滿意,但由於目前表函數內部不允許使用過程語言DDL ,因此一種可能的解決方法是簡單地使用如下所示的PROCEDURE

CREATE OR REPLACE PROCEDURE my_dataset.temp_procedure(filter_value INT64, table_name STRING)
BEGIN
    EXECUTE IMMEDIATE FORMAT(CONCAT(
        "SELECT year, COUNT(1) as record_count, ",
        "FROM %s                                ",
        "WHERE year = %d                        ",
        "GROUP BY year                          ",
        ";                                      "
    ), table_name, filter_value);
END;

CALL my_dataset.temp_procedure(2002, 'bigquery-public-data.usa_names.usa_1910_current');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM