【问题标题】:Postgres Window Function SyntaxPostgres 窗口函数语法
【发布时间】: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_idtime 都是在 users 上定义的列。

【问题讨论】:

  • 显然,我并不想只获取users 的前 20 行。我已简化查询以更清楚地说明语法错误

标签: sql postgresql window-functions


【解决方案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 BYHAVINGWHERE 子句。这是因为它们在逻辑上执行 在处理这些条款之后。此外,窗口函数执行 在常规聚合函数之后。这意味着包含 窗口函数的参数中的聚合函数调用,但是 反之亦然。

【讨论】:

  • 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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多