sql - 获取订单总和为1000的订单号

标签 sql postgresql sum window-functions cumulative-sum

我有一个订单表,其中每一行都有一个名为价格的列。这些订单中的每一个都有一个名为 created_at 的列,用于说明该订单的创建时间。

找出哪个订单使价格总额超过 1000 美元的好方法是什么?

因此,假设我有三个如下所示的订单:

Order 1: price: $800 - created_at: 2013/07/11 

Order 2: price: $100 - created_at: 2013/07/13 

Order 3: price: $300 - created_at: 2013/07/14 

我很想知道订单 3 是让我超过 1000 美元的那一个,因为如果我们加上 800 美元 + 100 美元 + 300 美元,就是使总金额大于 1000 美元的那 300 美元。

我可以执行什么查询来找到它?

最佳答案

用窗口聚合函数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's version 快,因为根据窗口函数中已经使用的相同顺序选择第一个比为每一行计算一个值要便宜很多,这不是 sargable .

我使用 sum_price >= 1000,所以达到 1000 也完全符合条件。如果只有 exceeding 应该符合条件,请使用 > 而不是 >=

The manual on window functions informs:

In addition to these functions, any built-in or user-defined aggregate function can be used as a window function

应该注意,与@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

Read the fine print in the manual.

但无论哪种方式都比较慢。

-> SQLfiddle

关于sql - 获取订单总和为1000的订单号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17727373/

相关文章:

sql - 替换Where子句中的concat操作

python - PGadmin未加载

postgresql - Postgres 9.1.24 > fatal error : SSL is not supported by this build

mysql - 使用 "group by"带条件和 "group by"计算的计数记录总和

sql - Oracle BLOB 与 VARCHAR

sql - 仅备份 SQL 架构?

php - 统计一个表中分层数据的所有子节点

excel - 将 Excel 工作表导入 Postgresql 数据库

sum - java8流分组聚合

linux - Linux中具有不同数字但具有相同模式的行的总和