Postgresql中的窗口函数过滤结果

ghhkc1vu  于 2024-01-07  发布在  PostgreSQL
关注(0)|答案(2)|浏览(141)

好吧,最初这只是我们和我的一个朋友开的一个玩笑,但它变成了一个有趣的技术问题:)
下面是一个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


如果我删除这个过滤器,总列得到正确的计算,结果正确排序,但 * 所有 * 的东西得到选择,这不是我想要的。
那么,我该如何做到这一点呢?我该如何只选择能装进包里的物品呢?

vdzxcuhz

vdzxcuhz1#

我不知道这是否符合“更优雅”的标准,但它的编写方式与Cybernate的解决方案不同(尽管本质上是相同的)。

WITH window_table AS 
( 
   SELECT s.*, 
          sum(volume) OVER previous_rows as total
   FROM stuff s
   WINDOW previous_rows as 
        (ORDER BY priority desc ROWS between UNBOUNDED PRECEDING and CURRENT ROW)
) 
SELECT * 
FROM window_table
WHERE total < 1000
ORDER BY priority DESC

字符串
如果你说的“更优雅”是指避免子选择的东西,那么答案是“不”

rwqw0loc

rwqw0loc2#

我没有使用过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;

字符串

相关问题