【问题标题】:BigQuery fails to save view that uses functionsBigQuery 无法保存使用函数的视图
【发布时间】:2017-07-03 01:20:23
【问题描述】:

我们将 BigQuery 与他们的新方言“standard”SQL 结合使用。 新的 SQL 支持用 SQL 而不是 JS 编写的内联函数,因此我们创建了一个函数来处理日期转换。

CREATE TEMPORARY FUNCTION
  STR_TO_TIMESTAMP(str STRING)
  RETURNS TIMESTAMP AS (PARSE_TIMESTAMP('%Y-%m-%dT%H:%M:%E*SZ', str));

它必须是临时函数,因为如果您尝试永久函数,Google 会返回 Error: Only temporary functions are currently supported; use CREATE TEMPORARY FUNCTION

如果您尝试使用使用内联函数的查询保存视图 - 您会收到以下错误:Failed to save view. No support for CREATE TEMPORARY FUNCTION statements inside views。 如果您试图超越它,并删除该功能(希望在查询期间添加它),您将收到此错误Failed to save view. Function not found: STR_TO_TIMESTAMP at [4:7]

关于如何解决这个问题的任何建议?我们有比所示示例更复杂的函数。

【问题讨论】:

标签: sql google-bigquery user-defined-functions


【解决方案1】:

由于问题被标记为resolved,BigQuery 现在支持permanents registration of UDFs。 为了在视图中使用您的 UDF,您需要先创建它。

CREATE OR REPLACE FUNCTION `ACCOUNT-NAME11111.test.STR_TO_TIMESTAMP`
    (str STRING) 
    RETURNS TIMESTAMP AS (PARSE_TIMESTAMP('%Y-%m-%dT%H:%M:%E*SZ', str));
  • 请注意,函数名称必须使用反引号。
  • 语句中没有TEMPORARY,因为该函数将被全局注册和持久化。
  • 由于 BigQuery 处理命名空间的方式,您必须在函数名称中同时包含项目名称和数据集名称 (test)。

一旦创建并成功运行,您就可以将其用作视图。

create view test.test_view as
select `ACCOUNT-NAME11111.test.STR_TO_TIMESTAMP`('2015-02-10T13:00:00Z') as ts

然后您可以直接查询您查看的内容,而无需在任何地方明确指定 UDF。

select * from test.test_view

【讨论】:

  • BigQuery 永久函数的文档链接在哪里,这里没有(至少现在):cloud.google.com/bigquery/docs/reference/standard-sql/…
  • 因为命名空间很长。是否可以将函数声明为变量?说将 my-long-names-project.my_lengthy_dataset.my_long_function_name 称为“func”?
  • @Benjamin 您可以使用临时功能来做到这一点。您可以在没有命名空间的情况下调用临时函数。因此,要么在 SQL 语句之前内联创建临时函数,要么创建一个具有短名称的临时函数来调用具有长名称的永久注册函数。
【解决方案2】:

根据文档 https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_function_statement ,该功能仍处于 Beta 阶段,但可行。可以在创建函数的同一数据集中查看函数,并且可以创建视图。 如果这对您有用,或者您有任何对其他人有帮助的发现,请分享。

【讨论】:

    【解决方案3】:

    仍然不支持保存使用临时函数创建的视图,但您可以做的是规划 SQL 查询(已针对最新 UI 推出),然后将其保存为表。这对我有用,但我想这取决于你想要的查询参数。

    ##standardSQL
    ## JS in SQL to extract multiple h.CDs at the same time. 
    CREATE TEMPORARY FUNCTION getCustomDimension(cd ARRAY<STRUCT< index INT64, 
    value STRING>>, index INT64)
    RETURNS STRING
    LANGUAGE js AS """
         for(var i = 0; i < cd.length; i++) {
         var item = cd[i];
         if(item.index == index) {
             return item.value
      }
    }
    return '';
    """;
    
    SELECT DISTINCT h.page.pagePath, getcustomDimension(h.customDimensions,20), fullVisitorId,h.page.pagePathLevel1, h.page.pagePathLevel2, h.page.pagePathLevel3, getcustomDimension(h.customDimensions,3)
    FROM
    `XXX.ga_sessions_*`,
    UNNEST(hits) AS h
    WHERE
        ### rolling timeframe
        _TABLE_SUFFIX = FORMAT_DATE('%Y%m%d',DATE_SUB(CURRENT_DATE(),INTERVAL YY DAY))
        AND h.type='PAGE'
    

    解决方案归功于https://medium.com/@JustinCarmony/strategies-for-easier-google-analytics-bigquery-analysis-custom-dimensions-cad8afe7a153

    【讨论】:

    • 如果您能提供一些代码,以便将来可能需要此功能的人更容易找到您的答案,那就太好了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多