BigQuery SQL中基于整数列创建分区表的DML语句编写及报错解决咨询
嘿,我来帮你搞定这个BigQuery分区表的创建问题!从你给出的报错信息和SQL语句来看,问题出在分区字段的定义不符合BigQuery的规则。
先看一下你原来的SQL语句:
CREATE TABLE cp1753.CI_DEV.PT_CI_STEP ( build_id INTEGER , step_name STRING , type STRING , start_time INTEGER , status STRING , timestamp INTEGER , stop_time INTEGER ) PARTITION BY stop_time INTEGER AS SELECT build_id,step_name ,type, start_time,status,timestamp , stop_time from cp1753.CI_DEV.ci_step
收到的报错很明确:
PARTITION BY expression must be DATE(<timestamp_column>), DATE(<datetime_column>), RANGE_BUCKET(<int64_column>, GENERATE_ARRAY(<int64_value>, <int64_value>[, <int64_value>]))
BigQuery不允许直接用整数类型字段作为分区键,它只支持两种合法的分区表达式:要么是将时间戳/日期类型转成DATE,要么是用RANGE_BUCKET函数定义整数范围分区。结合你的stop_time是整数类型(大概率是Unix时间戳),给你两种解决方案:
方案1:转成日期分区(适合按日期维度分区的场景)
如果你的stop_time是秒级Unix时间戳,我们可以把它转成DATE类型来做日期分区,修改后的SQL如下:
CREATE TABLE cp1753.CI_DEV.PT_CI_STEP ( build_id INTEGER , step_name STRING , type STRING , start_time INTEGER , status STRING , timestamp INTEGER , stop_time INTEGER ) PARTITION BY DATE(TIMESTAMP_SECONDS(stop_time)) AS SELECT build_id, step_name, type, start_time, status, timestamp, stop_time FROM cp1753.CI_DEV.ci_step;
如果stop_time是毫秒级时间戳,把TIMESTAMP_SECONDS换成TIMESTAMP_MILLIS即可。
方案2:用RANGE_BUCKET做整数范围分区(适合按数值区间分区的场景)
如果需要按stop_time的整数数值区间来分区(比如每86400秒/一天一个分区,或者自定义步长),可以用RANGE_BUCKET函数,示例SQL如下:
CREATE TABLE cp1753.CI_DEV.PT_CI_STEP ( build_id INTEGER , step_name STRING , type STRING , start_time INTEGER , status STRING , timestamp INTEGER , stop_time INTEGER ) PARTITION BY RANGE_BUCKET(stop_time, GENERATE_ARRAY(0, 1700000000, 86400)) AS SELECT build_id, step_name, type, start_time, status, timestamp, stop_time FROM cp1753.CI_DEV.ci_step;
这里的GENERATE_ARRAY(0, 1700000000, 86400)表示:
- 分区起始值为0
- 分区结束值为1700000000(你可以根据自己的数据范围调整)
- 每个分区的步长为86400(即一天的秒数,也可以自定义其他数值)
总结一下:你只需要把PARTITION BY后面的表达式改成BigQuery支持的两种形式之一,就能成功创建分区表啦~
内容的提问来源于stack exchange,提问作者AHM

