按窗口函数过滤导致Postgresql

Max*_*yko 22 sql postgresql window-functions

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

我有下stuff表:

CREATE TABLE stuff
(
    id serial PRIMARY KEY,
    volume integer NOT NULL DEFAULT 0,
    priority smallint NOT NULL DEFAULT 0,
);
Run Code Online (Sandbox Code Playgroud)

该表包含我所有内容的记录,包括各自的数量和优先级(我需要多少).

比方说,我有一个指定体积的包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
Run Code Online (Sandbox Code Playgroud)

然而,它的问题在于Postgres抱怨:

ERROR:  column "total" does not exist
LINE 3:  where total < 1000
Run Code Online (Sandbox Code Playgroud)

如果我删除了这个过滤器,总列得到了正确的计算,结果排序正确,但所有的东西都被选中,这不是我想要的.

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

Cha*_*ndu 15

我没有使用过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;
Run Code Online (Sandbox Code Playgroud)

  • 看起来 WINDOW 函数不能在 WHERE、HAVING 子句中使用(Oracle 中也是如此)。检查:http://www.postgresql.org/docs/current/static/tutorial-window.html (2认同)

a_h*_*ame 15

我不知道这是否符合"更优雅"的条件,但它的编写方式与Cyber​​nate的解决方案不同(尽管它基本相同)

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 

如果"更优雅"是指避免子选择的东西,那么答案就是"不"