[英]bigquery type check operator? like typeof in Javascript; or workaround
在一个BigQuery 表的schema 不断发展的项目中,我想知道有没有一种好的方法可以通用地编写SQL 代码?
例如,版本 1 中的功能标志字段是一个简单的 BOOLEAN,但后来演变为 FLOAT 来表示 0(假)和 1(真)之间的值,然后针对每个模式修订更改为多个 BOOLEAN 的 STRUCT我也更改了表名,所以现在我有当前表v3和旧表v2和v1,旧表有历史信息有时仍然有用,而且体积很大不利于全部迁移到v3模式; 由于 bigquery 主要用作加载一次然后仅附加,或者大多数情况下只读数据库,只从旧表查询就足够了; 使用表名通配符我可以在单个查询中查询所有表,但不确定如何处理不同的输入类型,是否有动态类型检查功能来编写查询 SQL,如 Javascript 中的这种typeof
运算符:?
CASE typeof feature
WHEN "BOOLEAN" THEN ... # handle v1
WHEN "FLOAT" THEN ... # handle v2
WHEN "STRUCT" THEN ... # handle v3
WHEN ...
ELSE
END
或者你会建议解决什么问题? 如果项目的性质具有不断发展的模式(由于快速变化的需求或许多其他常见原因)
FORMAT('%T', obj)
将任何键入的值转换为文字字符串。 可用于实现 SQL UDF 中的typeof
函数。
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"
详尽的测试和结果放在要点中,因为它太长了。
您可以使用基于社区的公共 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
注意:BigQuery 在执行查询之前会进行类型检查,因此THEN
子句中的表达式必须在所有WHEN-THEN
对中都有效。
或者你会建议解决什么问题?
所以,换句话说你的想法 - 你正在考虑来自具有不同模式的不同表的 UNION ALL 。 不幸的是,由于模式不同,这不会成功!
我推荐以下解决方法:
您需要为每个版本创建一个视图,以使每个视图的架构相同。 请参见下面的示例
#standardSQL
WITH table_v1 AS (
SELECT 1 AS id, TRUE AS feature UNION ALL
SELECT 2 AS id, FALSE AS feature
),
table_v2 AS (
SELECT 3 AS id, 0.2 AS feature UNION ALL
SELECT 4 AS id, 0.8 AS feature
),
table_v3 AS (
SELECT 5 AS id, STRUCT<x BOOL, y bool, z bool>(TRUE, FALSE, TRUE) AS feature UNION ALL
SELECT 6 AS id, (TRUE, TRUE, TRUE) AS feature
),
view_v1 AS (
SELECT id, feature
FROM table_v1
),
view_v2 AS (
SELECT id, CASE WHEN feature < 0.5 THEN TRUE ELSE FALSE END AS feature -- handle v2
FROM table_v2
),
view_v3 AS (
SELECT id, feature.x OR feature.y OR feature.z AS feature -- handle v3
FROM table_v3
),
table_all AS (
SELECT * FROM view_v1 UNION ALL
SELECT * FROM view_v2 UNION ALL
SELECT * FROM view_v3
)
SELECT *
FROM table_all
WHERE feature
-- ORDER BY id
保存视图时 - 您将能够对这些视图使用通配符
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.