BigQuery添加ORDER BY后报表达式未分组错误如何解决
报错原因
这个报错是BigQuery解析器的典型隐蔽坑,核心触发点是ORDER BY子句中的列名和SELECT、GROUP BY里的写法存在大小写差异:
- 你在SELECT、GROUP BY中引用产品ID列时写的是全小写的
p.id - 但ORDER BY子句中写的是首字母大写的
p.Id
在带GROUP BY的聚合查询场景下,如果ORDER BY里带表别名的列名和SELECT/GROUP BY中的定义不是完全字符级匹配(哪怕只是大小写区别),BigQuery解析器会错误地重新全量校验SELECT列表的所有表达式,无法识别你已经在GROUP BY中对pv.data_tstamp做了分组处理,就会抛出这个看起来和ORDER BY完全无关的报错,这也是为什么删掉ORDER BY子句后查询能正常运行的原因。
顺便提一句:你当前SQL把左表pv的时间过滤条件写在WHERE中,会实际把LEFT JOIN转换成INNER JOIN,不会返回无访问记录的产品,如果这不符合你的业务预期,需要把这部分过滤条件挪到LEFT JOIN的ON子句后,不过这个逻辑问题不会触发当前的语法报错。
修改方案
三种改法任选其一即可解决问题:
- 最直接的改法:把ORDER BY里的列名改成和前面完全一致的小写写法
ORDER BY p.id
- 最不容易踩坑的写法:ORDER BY直接引用SELECT返回的列名,不带表别名,彻底规避大小写匹配问题
ORDER BY id
- 聚合查询常用的简洁写法:按SELECT列表的列序号排序,
p.id是第2个返回列,直接写序号即可,还能避免重复书写长列名
ORDER BY 2
以下是优化后的完整SQL参考,BigQuery原生支持GROUP BY直接引用SELECT中定义的别名,不用重复写冗长的转换表达式:
SELECT p.title, p.id, SUM(view) AS Views, CAST(EXTRACT(DATE FROM pv.data_tstamp) AS STRING) AS dateInserted FROM products AS p LEFT JOIN productViews AS pv ON p.sku = pv.sku -- 若需要保留无访问量的产品,把时间过滤条件挪到此处即可 -- AND pv.data_tstamp >= TIMESTAMP('2022-06-20 00:00:00') -- AND pv.data_tstamp <= TIMESTAMP('2022-06-29 00:00:00') WHERE pv.data_tstamp >= TIMESTAMP('2022-06-20 00:00:00') AND pv.data_tstamp <= TIMESTAMP('2022-06-29 00:00:00') GROUP BY p.title, p.id, dateInserted ORDER BY id
内容的提问来源于stack exchange,提问作者cam
相关产品推荐
相关产品推荐

