我在BQ中运行了一组相当复杂的嵌套聚合,并遇到了以下问题:
如果我在查询的最高级别请求ROW_NUMBER(),BQ似乎无法识别我的列名。如果我在查询的最里面请求ROW_NUMBER(),我会神奇地得到一个行号。
这是我查询的(简化)版本:
SELECT
ROW_NUMBER() OVER() row_id, // query fails with ROW_NUMBER() here
price,
store,
week,
f.product product,
COUNT(DISTINCT f.product) OVER (PARTITION BY store, week) product_count,
price_max-price_min weekly_price_range,
FROM (
SELECT
MIN(price) OVER (PARTITION BY store, week) price_min,
MAX(price) OVER (PARTITION BY store, week) price_max,
*
FROM (
SELECT
dollars / units price,
*
FROM store_sales_facts f
JOIN product_facts p
ON p.product = f.product
)
)
如果我删除了对ROW_NUMBER()的请求,查询会成功。如果我包含ROW_NUMBER()函数,则BQ会失败并显示"错误:字段'价格'找不到"
我使用以下方法作为解决方法,但我很好奇是否有人可以解释为什么这有效,而上述情况并非如此?
SELECT
row_id,
price,
store,
week,
f.product product,
COUNT(DISTINCT f.product) OVER (PARTITION BY store, week) product_count,
price_max-price_min weekly_price_range,
FROM (
SELECT
MIN(price) OVER (PARTITION BY store, week) price_min,
MAX(price) OVER (PARTITION BY store, week) price_max,
*
FROM (
SELECT
ROW_NUMBER() OVER() row_id, // query succeeds with ROW_NUMBER() here
dollars / units price,
*
FROM store_sales_facts f
JOIN product_facts p
ON p.product = f.product
)
)
ORDER BY row_id
我理解ROW_NUMBER()窗口函数最近才被添加。这是函数本身的怪癖吗?任何帮助将不胜感激。
答案 0 :(得分:1)
假设“我们看到的是您正在执行的内容”,那么我建议核心问题可能是缺少对列的表引用。事实和维度表共享至少一个列名(产品),因此您可能会有歧义。因此,我建议的第二件事是对表进行别名并使用别名和每个列引用,但这当然是在第一次建议之后发生的,即使用显式列名替换 if (activity.Type == ActivityTypes.Message)
{
var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
Activity isTypingReply = activity.CreateReply();
isTypingReply.Type = ActivityTypes.Typing;
await connector.Conversations.ReplyToActivityAsync(isTypingReply);
await Conversation.SendAsync(activity, () => new RootDialog());
}
(与相关的表别名)。
select *
row_number()的具体问题我无法复制甚至测试,但在前一个问题RANK or ROW_NUMBER in BigQuery over a large dataset,似乎对该函数的可伸缩性存在一些疑问。我建议你可能需要考虑一些分区,或者完全避免分区,因为我不知道它会给你带来什么价值。如果你对每一行都有一些独特的引用,那么使用事实表(f.id I presume)的已经唯一的行引用形式会更有效。
SELECT
ROW_NUMBER() OVER () row_id
, d.price
, d.store
, d.WEEK
, d.product
, COUNT(DISTINCT d.product) OVER (PARTITION BY d.store, d.WEEK) product_count
, d.price_max - d.price_min weekly_price_range
FROM (
SELECT
MIN(p.price) OVER (PARTITION BY store, WEEK) price_min
, MAX(p.price) OVER (PARTITION BY store, WEEK) price_max
, p.product, p.store, p.week
FROM (
SELECT
f.dollars / f.units price
, f.product
, s.store
, f.WEEK
FROM store_sales_facts f
JOIN product_facts p ON p.product = f.product
) p
) d
的另一个长期可能性是,即使您并不真正关心结果行编号的顺序,over子句也可能需要按参数排序。此问题存在于某些其他dbs中,并通过对常量(例如“select null”或“select 1”)进行排序来解决,例如
row_number() over()
但是我没有证据表明BigQuery中存在此问题,或者通过该解决方法解决了这个问题。