bigquery 类型检查运算符?就像 JavaScript 中的 typeof 一样;或解决方法

use*_*998 4 google-bigquery

在 BigQuery 表的架构不断发展的项目中,我想知道是否有一种通用的 SQL 代码编写好方法?

例如,版本 1 中的功能标志字段是一个简单的 BOOLEAN,但后来演变为 FLOAT 来表示 0(假)和 1(真)之间的值,然后针对每个模式修订更改为多个 BOOLEAN 的 STRUCT我也更改了表名,所以现在我有当前表 v3 和旧表 v2 和 v1,旧表有历史信息有时仍然有用,而且体积大不利于全部迁移到 v3 模式;由于bigquery主要用作一次加载然后仅追加,或者大多数情况下用作只读数据库,因此只需从旧表中查询就足够了;使用表名通配符我可以在单个查询中查询所有表,但不确定如何处理不同的输入类型,是否有一个动态类型检查函数可以像typeofJavascript中的这样的运算符编写查询SQL:?

CASE typeof feature
  WHEN "BOOLEAN" THEN ... # handle v1
  WHEN "FLOAT"   THEN ... # handle v2
  WHEN "STRUCT"  THEN ... # handle v3
  WHEN ...
  ELSE
END
Run Code Online (Sandbox Code Playgroud)

或者您建议如何解决?项目的性质是否具有不断发展的模式(由于快速变化的需求或许多其他常见原因)

aps*_*ndb 10

FORMAT('%T', obj)将任何键入的值转换为文字字符串。它可以用来实现typeofSQL UDF中的功能。

CREATE TEMP FUNCTION typeof_literal(input STRING)
AS (
      CASE
        -- Process NUMERIC, DATE, DATETIME, TIME, TIMESTAMP,
        WHEN REGEXP_CONTAINS(input, r'^[A-Z]+ "') THEN REGEXP_EXTRACT(input, r'^([A-Z]+) "')
        WHEN REGEXP_CONTAINS(input, r'^-?[0-9]*$') THEN 'INT64'
        WHEN REGEXP_CONTAINS(input, r'^(-?[0-9]+[.e].*|CAST\("([^"]*)" AS FLOAT64\))$') THEN 'FLOAT64'
        WHEN input IN ('true', 'false') THEN 'BOOL'
        WHEN input LIKE '"%' THEN 'STRING'
        WHEN input LIKE 'b"%' THEN 'BYTES'
        WHEN input LIKE '[%' THEN 'ARRAY'
        WHEN REGEXP_CONTAINS(input, r'^(STRUCT)?\(') THEN 'STRUCT'
        WHEN input LIKE 'ST_%' THEN 'GEOGRAPHY'
        WHEN input = 'NULL' THEN 'NULL'
      ELSE
      'UNKNOWN'
    END );

CREATE TEMP FUNCTION typeof(input ANY TYPE)
AS ( typeof_literal(FORMAT('%T', input)) );

-- You can pass any type value to typeof function
SELECT typeof(CURRENT_TIMESTAMP());
-- result: "TIMESTAMP"
SELECT typeof(STRUCT(1, 2, 3));
-- result: "STRUCT"

Run Code Online (Sandbox Code Playgroud)

由于太长,详尽的测试和结果被放在要点中。

更新

您可以使用基于社区的公共 UDF bqutil.fn.typeof

CASE bqutil.fn.typeof(feature)
  WHEN "BOOLEAN" THEN ... # handle v1
  WHEN "FLOAT"   THEN ... # handle v2
  WHEN "STRUCT"  THEN ... # handle v3
  WHEN ...
  ELSE
END
Run Code Online (Sandbox Code Playgroud)

注意:BigQuery 在执行查询之前会进行类型检查,因此THEN子句中的表达式必须在所有对中都有效WHEN-THEN