好的,最初这只是我和我的一个朋友开的一个玩笑,但它变成了一个有趣的技术问题:)
我有以下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
如果删除此过滤器,则会正确计算总列数,对结果进行正确排序,但所有内容都会被选中,这不是我想要的。
那么,我该怎么做?如何仅选择可放入包中的物品?
答案 0 :(得分:13)
我没有使用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;
答案 1 :(得分:13)
我不知道这是否符合“更优雅”的条件,但它的编写方式与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
如果“更优雅”是指避免子选择的东西,那么答案就是“不”