考虑一个为不同生产设施捕获传感器数据的企业。每个设施,我们创建一个聚合查询,将值平均到 5 分钟的时间段。此查询存在于一长串 with 子句中,并将数据写入表(称为aggregation_table)。
现在我的问题是:目前我们有 n 个查询运行,它们运行完全相同的逻辑,唯一不同的是表名(有时是列名,但现在让我们忽略它)。
我不想管理 n 个基本相同的不同脚本,而是想将它放在一个能够像这样工作的存储过程中:
CALL aggregation_query(facility_name) -> 为该设施解析不同的表,然后在不同的 with 子句中使用它们
最重要的是,我不想有这么长的一组子句来给我最终结果,我想将它们分成可参数化的逻辑块,例如,如果我为设施 A 调用上述存储过程,我希望能够在这些不同的函数中传递/使用这个表名,输出可以在下一个语句中重复使用(就像你对 with 子句所做的那样)。
关于我为什么要将其分成可重用块的另一个论点是因为我们在此聚合查询上有许多“派生”,例如用于管理历史数据、更正数据或将传感器数据置于另一个聚合级别。随着这些变得过于复杂,管理它们要容易得多,而不必每次都复制粘贴和调整它们。
在当前设置中,知道我仅有权使用普通 BigQuery 可能很有用,因为我的团队不允许访问 CI/CD/调度和存储库。(这意味着我无法通过部署 n 个不同版本的过程和功能的 CI/CD 来解决问题)
所以最后,我想只使用 bigquery 得到这样的结果:
CREATE OR REPLACE PROCEDURE
`aggregation_function`()
BEGIN
DECLARE
tablename STRING;
DECLARE
active_table_name STRING; ##get list OF tables CREATE TEMP TABLE tableNames AS
SELECT
table_catalog,
table_schema,
table_name
FROM
`catalog.schema.INFORMATION_SCHEMA.TABLES`
WHERE
table_name = tablename;
WHILE
(
SELECT
COUNT(*)
FROM
tableNames) >= 1 DO ##build dataset + TABLE name
SET
active_table_name = CONCAT('`',table_catalog,'.',table_schema,'.' ,table_name,'`'); ##use concat TO build string AND execute
EXECUTE IMMEDIATE '''
INSERT INTO
`aggregation_table_for_facility` (timeslot, sensor_name, AVG_VALUE )
WITH
STEP_1 AS (
SELECT
*
FROM
my_table_function_step_1(active_table_name,
parameter1,
parameter2) ),
STEP_2 AS (
SELECT
*
FROM
my_table_function_step_2(STEP_1,
parameter1,
parameter2) )
SELECT * FROM STEP_2
'''
USING active_table_name as active_table_name;
DELETE
FROM
tableNames
WHERE
table_name = tablename;
END WHILE
;
END
;
我希望有人可以在标准 SQL / Bigquery 中制作一个关于我如何做到这一点的片段,所以基本上:
接受字符串变量并能够将其用作表的存储过程(在上述方法中部分解决,但不确定是否有更好的方法)
(table) 函数,该函数也能够接受这个 table_name 参数并返回一个可以在下一个 with 子句中使用的表(或者写入临时表)