【发布时间】:2021-03-05 20:18:10
【问题描述】:
我遇到了一个有趣的情况,内部查询无法访问GROUP BY 子句中使用的截断值。如何从父查询访问 trunc-modified GROUP BY 子句?
这是一个精简版:
SELECT
date_trunc('week', mainEvent.timestamp::date + 1)::date -1 AS weekly,
(
SELECT sum(p.value)
FROM myschema.purchase as p
WHERE p.non_unique_id = mainEvent.non_unique_id
AND date_trunc('week', p.timestamp::date + 1)::date -1
= date_trunc('week', mainEvent.timestamp::date + 1)
GROUP BY (date_trunc('week', p.timestamp::date + 1)::date -1)::date
) as percent_of_week
FROM myschema.event as mainEvent
WHERE mainEvent.internal_feed_name IS NOT NULL
GROUP BY weekly, mainEvent.non_unique_id;
这会产生错误subquery uses ungrouped column "mainevent.timestamp" from outer query Position: 1587
我尝试将外部 GROUP BY 子句更改为:
GROUP BY date_trunc('week', mainEvent.timestamp::date + 1)::date -1, mainEvent.non_unique_id
但它返回相同的错误。但是,如果我从外部 GROUP BY 中删除 trunc
GROUP BY mainEvent.timestamp
引用外部查询的GROUP BY“有效”。这让我认为这原则上有效,但 PostGres 不理解变异的分组。也许有一些语法糖可以使这项工作?有没有办法通过创建一个临时表来做到这一点?我还尝试了窗口函数sum(over) 等的一些变体,但我仍然遇到引用父分组列的问题...我不想按原始时间戳分组,我想每周分组。
目标:我需要在我做伪代码的地方汇总数据:(x / sum(x) in week) as percent_of_week 每周总计的总和。
所以一些数学除以组的总和。实际上,子查询有一个与每个唯一相关的分子(为简洁起见,此处省略),除以主组week 的总和,这就是为什么简单地加入不起作用的原因。我的架构中也没有外键(原始分析数据)。
【问题讨论】:
-
嗨,有趣,也许用 cte 会更容易? postgresqltutorial.com/postgresql-cte
-
我用
GROUP BY进行子查询几乎从来都不是人们想要的——因为它可以返回多行并产生错误。样本数据、期望的结果以及对逻辑的清晰解释会有所帮助。 -
@GordonLinoff 好吧,如果是这种情况,我会收到运行前错误
subquery returns multiple rows。情况并非如此,当我使用非截断分组时,我得到了预期的 1 行计数。我在其他地方使用这种模式,子查询可以访问父GROUP BY。 -
如果将子查询中的
date_trunc('week', mainEvent.timestamp::date + 1)替换为weekly::date +1会怎样?或者只是weekly并将比较的另一边设为-2 而不是-1?这可能使数据库能够识别出被比较的值取决于GROUP BY列而不是基础列。 -
@Fred 我试过了,但是别名
weekly不适用于内部查询。
标签: sql postgresql window-functions