使用窗口聚合函数计算运行总和后sum()
,只需根据created_at
超过 1000 选择第一行:
SELECT *
FROM (
SELECT order_id, created_at
, sum(price) OVER (ORDER BY created_at) AS sum_price
FROM orders
) sub
WHERE sum_price >= 1000
ORDER BY created_at
LIMIT 1;
这应该比@Gordon 的版本快,因为根据窗口函数中已经使用的相同顺序选择第一个比为每一行计算一个值便宜得多,这不是sargable。
我使用sum_price >= 1000
,所以达到 1000 也完全符合条件。如果仅超出应限定使用>
而不是>=
.
窗口函数手册告知:
除了这些函数之外,任何内置或用户定义的聚合函数都可以用作窗口函数
应该注意的是,与@Gordon 的查询相反,此查询始终只提供一行。在具有相同的多行created_at
跨越 1000 障碍的情况下,它们都将符合 Gordon 的答案(或者它会失败,见下文),而只有one
在我的答案中被选中。只要您不添加更多项目ORDER BY
作为决胜局,这将是任意的。喜欢:
ORDER BY created_at, order_id
此查询中有两个 ORDER BY 实例,碰巧您可以修改其中一个或两个以使其工作。这样做是为了使排序顺序相同,这应该是最快的。
实际上,对于这个测试用例,Gordon 的版本会完全失败:
CREATE TEMP TABLE orders(order_id int, price int, created_at date);
INSERT INTO orders VALUES
(1, 500, '2013-07-01')
,(2, 400, '2013-07-02')
,(3, 100, '2013-07-03')
,(4, 100, '2013-07-03')
,(5, 100, '2013-07-03');
您可以通过使窗口函数中的排序顺序独一无二来修复它,如上所示。
或者您可以将窗口函数的框架定义更改为:
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
阅读手册中的细则。
但无论哪种方式都比较慢。
-> SQL小提琴