【发布时间】:2016-09-20 13:09:52
【问题描述】:
我们正在将我们的系统从 SQL Server 移植到 PostgreSQL。因此,我们计算了过去 3 个月所有日期所有公司的平均每日营业额。以下是相同的简化查询
SELECT B.Company, B.Dt, B.Turnover, (Select distinct
PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY Turnover) OVER (PARTITION
BY B.Company, B.Dt) from Example_Tbl AS G where G.Company = B.Company
and G.Dt <= B.Dt and G.Dt > DateAdd(dd, -92, B.Dt)) as
Med_3m_Turnover FROM Example_Tbl B;
问题在于 PostgreSQL 不支持将percentile_disc() 用作窗口函数。错误信息是:
错误:有序集聚合 percentile_disc 不支持 OVER
有什么方法可以在 PostgreSQL 中使用其他东西来实现相同的功能。
编辑:这是 Example_Tbl 中的示例输入数据
Company Dt Turnover
x 1 10
x 2 45
x 3 20
y 1 300
y 2 100
y 3 200
输出应如下所示。请注意,我们现在忽略 3 个月,每个公司只有 3 行
Company Dt Turnover Med_3m_Turnover
x 1 10 10
x 2 45 10 or 45 depending on percentile_desc
x 3 20 20
y 1 300 300
y 2 100 300 or 100 depending on percentile_desc
y 3 50 100
【问题讨论】:
-
我一定没有完全理解您的查询,因为我不确定
select distinct percentile_disc(...部分有时不会返回超过一行,这会产生错误。 -
@sstan。如果没有 distinct 子句,子查询将返回多个值并引发错误。不同的是完全停止。
-
在我看来您根本不需要
OVER,因为您的子查询应该只返回一行,然后只使用WITHIN GROUP而没有WINDOW FUNCTION。 -
@John:我明白了,但是查询不能返回多个 distinct 值吗?这是我不清楚的部分。我之所以这么说是因为partition子句是by
B.Company, B.Dt,而子查询在G.Dt <= B.Dt上有一个过滤条件,这意味着可能有多个B.Company, B.Dt组合,因此也可以返回多个不同的percentile_disc价值观。如果您的查询有效,我知道我一定是错的,但这就是我试图理解的地方。 -
@John:实际上,我刚刚意识到为什么查询永远不会失败。这是因为
partition by子句使用B.Company, B.Dt(该行的常量值)而不是G.Company, G.Dt。不确定这是否是故意的(我不这么认为),但这就是防止错误的原因。不确定你是否得到了你想要的结果。
标签: sql postgresql window-functions