Postgres 窗口函数语法
Posted
技术标签:
【中文标题】Postgres 窗口函数语法【英文标题】:Postgres Window Function Syntax 【发布时间】:2013-02-23 01:10:06 【问题描述】:为什么会出现以下查询:
select ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY time DESC) as rownum FROM users where rownum < 20;
产生以下错误?
ERROR: column "rownum" does not exist
LINE 1: ...d ORDER BY time DESC) as rownum FROM users where rownum < 2...
如何构造这个查询,以便获得前 20 个项目,由我的窗口函数定义?
user_id
和 time
都是在 users
上定义的列。
【问题讨论】:
显然,我并不想只获取users
的前 20 行。我已简化查询以更清楚地说明语法错误
【参考方案1】:
它会像这样工作:
SELECT *
FROM (
SELECT ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY time DESC) AS rownum
FROM users
) x
WHERE rownum < 20;
这里的重点是事件的顺序。窗口函数在WHERE
子句之后应用。因此rownum
尚不可见。您必须将其放入子查询或 CTE 中,并在下一个查询级别对 rownum
应用 WHERE
子句。
Per documentation:
仅在
SELECT
列表和ORDER BY
中允许使用窗口函数 查询的子句。它们在其他地方被禁止,例如GROUP BY
,HAVING
和WHERE
子句。这是因为它们在逻辑上执行 在处理这些条款之后。此外,窗口函数执行 在常规聚合函数之后。这意味着包含 窗口函数的参数中的聚合函数调用,但是 反之亦然。
【讨论】:
Here可以看到过滤了WHERE谓词后处理了Window Functions。【参考方案2】:因为where
子句在选择之前执行,所以它还不知道该别名。这样做:
select *
from (
select ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY time DESC) as rownum
FROM users
) s
where rownum < 20;
【讨论】:
以上是关于Postgres 窗口函数语法的主要内容,如果未能解决你的问题,请参考以下文章
如何在带有 Postgres 的动态框架中使用窗口函数中的列值?