【问题标题】:Filtering by window function result in Postgresql在 Postgresql 中按窗口函数结果过滤
【发布时间】:2011-06-29 21:01:25
【问题描述】:

好的,最初这只是我们和我朋友的一个玩笑,但后来变成了有趣的技术问题:)

我有以下stuff 表:

CREATE TABLE stuff
(
    id serial PRIMARY KEY,
    volume integer NOT NULL DEFAULT 0,
    priority smallint NOT NULL DEFAULT 0,
);

该表包含我所有东西的记录,以及相应的数量和优先级(我需要多少)。

我有一个指定体积的包,比如1000。我想从表中选择所有我可以放入袋子的东西,先把最重要的东西打包。

这似乎是使用窗口函数的情况,所以这是我想出的查询:

select s.*, sum(volume) OVER previous_rows as total
 from stuff s
 where total < 1000
 WINDOW previous_rows as
  (ORDER BY priority desc ROWS between UNBOUNDED PRECEDING and CURRENT ROW)
 order by priority desc

然而,问题在于 Postgres 抱怨:

ERROR:  column "total" does not exist
LINE 3:  where total < 1000

如果我删除此过滤器,总列会正确计算,结果会正确排序,但 所有 内容都会被选中,这不是我想要的。

那么,我该怎么做呢?如何只选择可以放入包中的物品?

【问题讨论】:

    标签: sql postgresql window-functions


    【解决方案1】:

    我不知道这是否称得上“更优雅”,但它的编写方式与 Cyber​​nate 的解决方案不同(尽管本质上是相同的)

    与 window_table 作为 ( 选择 s.*, sum(volume) OVER previous_rows as total FROM 东西 WINDOW previous_rows 为 (ORDER BY priority desc ROWS 在 UNBOUNDED PRECEDING 和 CURRENT ROW 之间) ) 选择 * FROM window_table 总计

    如果“更优雅”是指避免子选择,那么答案是“否”

    【讨论】:

    • 请注意 postgres 实现 CTE,因此这可能比子查询版本“更优雅”,因为它更易于阅读,但您可能会遇到性能下降
    • @miro:自 V12 以来不再存在,实现 CTE 实际上提高了性能并不少见(从 11 迁移到 12 时我必须更改一些查询并添加 materialized 关键字以获得旧性能回归)
    【解决方案2】:

    我没有使用过 PostgreSQL。但是,我最好的猜测是使用内联视图。

    SELECT a.*
    FROM (
        SELECT s.*, sum(volume) OVER previous_rows AS total
        FROM stuff AS s
        WINDOW previous_rows AS (
             ORDER BY priority desc
             ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        )
        ORDER BY priority DESC
    ) AS a
    WHERE a.total < 1000;
    

    【讨论】:

    • 这很好用。但是,我想知道是否存在更优雅的解决方案。很奇怪,我不能直接根据“total”过滤...
    • 看起来WINDOW函数不能用在WHERE、HAVING子句中(Oracle也是这样)。检查:postgresql.org/docs/current/static/tutorial-window.html
    猜你喜欢
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 2018-12-15
    • 2012-04-20
    • 1970-01-01
    相关资源
    最近更新 更多