sql - PostgreSQL 中的 PERCENTILE_DISC() 作为窗口函数

标签 sql postgresql window-functions

我们正在将我们的系统从 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() 用作窗口函数。错误信息是:

ERROR: OVER is not supported for ordered-set aggregate percentile_disc

有什么方法可以使用 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  

最佳答案

您的分区依据子句(PARTITION BY B.Company, B.Dt) 正在使用来自外部查询(别名 B)的值,而不是子查询(别名 G),后者不是一开始对我来说不是很明显。因为 B.companyB.Dt 的值在子查询的每次执行中都是常量,所以您的分区子句实际上与简单地这样写没有什么不同:

... over (partition by 1)

如果需要,您可以在 SQL Server 中进行测试,但您会发现结果是一样的。现在,我不知道使用 B.Company, B.Dt 是有意还是无意,但实际上,这意味着 partition by 子句实际上并不是分区任何东西。

因此,好消息是,要在 PostgreSQL 中编写等效查询,您只需省略 OVER (PARTITION BY B.Company, B.Dt) 子句,行为将与 SQL Server 中的相同。

关于sql - PostgreSQL 中的 PERCENTILE_DISC() 作为窗口函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39595038/

相关文章:

sql - SQL Server 子节点中的空白 xml 命名空间

postgresql - 从导致聚合条件为真的记录中获取字段值

sql - PostgreSQL 函数返回表或 SETOF

sql - 使用 partition by 子句时如何在 Postgres 中选择特定分区

sql - SQL Server 中求和函数的工作方式

mysql - 如何获得每组的第一行?

MySQL、PostgreSQL、SQLite 的 SQL 方案转换脚本......

php - 如何使用 Zend_Db_Adapter 在每次调用 "query"时运行多个 SQL 查询?

涉及join的Mysql更新语句

PostgreSQL 中的 SQL 查询问题