PostgreSQL 中的 PERCENTILE_DISC() 作为窗口函数
Posted
技术标签:
【中文标题】PostgreSQL 中的 PERCENTILE_DISC() 作为窗口函数【英文标题】:PERCENTILE_DISC() in PostgreSQL as a window function 【发布时间】: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子句是byB.Company, B.Dt
,而子查询在G.Dt <= B.Dt
上有一个过滤条件,这意味着可能有多个B.Company, B.Dt
组合,因此也可以返回多个不同的percentile_disc价值观。如果您的查询有效,我知道我一定是错的,但这就是我试图理解的地方。
@John:实际上,我刚刚意识到为什么查询永远不会失败。这是因为partition by
子句使用B.Company, B.Dt
(该行的常量值)而不是G.Company, G.Dt
。不确定这是否是故意的(我不这么认为),但这就是防止错误的原因。不确定你是否得到了你想要的结果。
【参考方案1】:
您的 partition by
子句 (PARTITION
BY B.Company, B.Dt
) 正在使用来自外部查询的值(别名 B
),而不是子查询(别名 G
),这对我来说一开始并不明显。因为 B.company
和 B.Dt
的值对于子查询的每次执行都是恒定的,所以你的分区子句实际上与简单地写成这样没有什么不同:
... over (partition by 1)
如果你愿意,你可以在 SQL Server 中测试它,但你会发现结果是一样的。现在,我不知道使用B.Company, B.Dt
是不是故意的,但实际上,这意味着partition by
子句实际上并没有对任何东西进行分区。
因此,对您来说,好消息是要在 PostgreSQL 中编写等效查询,您只需完全省略 OVER (PARTITION
BY B.Company, B.Dt)
子句,其行为将与 SQL Server 中相同。
【讨论】:
谢谢@sstan。是的,Query 与“over (partition by 1)”相同。我想我们一定把它放在那里,因为 SQL Server 需要 WITHIN GROUP 和 OVER 子句,尽管我不知道为什么。没有它们中的任何一个,它都会出错。我将删除 postgres 中的分区引用。当我继续迁移时,我确信我会遇到需要两者的查询。当我到达那里时会发布另一个问题。再次感谢以上是关于PostgreSQL 中的 PERCENTILE_DISC() 作为窗口函数的主要内容,如果未能解决你的问题,请参考以下文章
9_InfluxDB常用函数选择类函数(TOP() BOTTOM() FIRST() LAST() MAX() MIN() PERCENTILE())
apache spark sql中的等效percentile_cont函数
如何在 postgreSQL 中创建 generate_series 函数?
急求Excel 函数percentile 是怎样算出来的?如:percentile(A1:A8, 0.8) , 是A1至A8相加,再乘以0.8吗?