跳转至

2893. 计算每个区间内的订单 🔒

难度中等

题目描述

表: Orders

+-------------+------+ 
| Column Name | Type | 
+-------------+------+ 
| minute      | int  | 
| order_count | int  |
+-------------+------+
minute 是该表的主键。
该表的每一行包含分钟数以及在特定分钟数内收到的订单数量。总行数将是 6 的倍数。

编写一个查询,计算每个 区间 内的 总订单数量。 每个区间被定义为 6 分钟的组合。

  •  1 到 6 分钟属于第 1 个区间,而 7 到 12 分钟属于第 2 个区间,以此类推。

按 升序顺序 返回结果表,按 interval_no 排序。

结果表的格式如下示例所示。

 

示例 1:

输入:
Orders table:
+--------+-------------+
| minute | order_count | 
+--------+-------------+
| 1      | 0           |
| 2      | 2           | 
| 3      | 4           | 
| 4      | 6           | 
| 5      | 1           | 
| 6      | 4           | 
| 7      | 1           | 
| 8      | 2           | 
| 9      | 4           | 
| 10     | 1           | 
| 11     | 4           | 
| 12     | 6           | 
+--------+-------------+
输出:
+-------------+--------------+
| interval_no | total_orders | 
+-------------+--------------+
| 1           | 17           | 
| 2           | 18           |    
+-------------+--------------+
解释:
- 区间号 1 包括从 1 到 6 分钟的时间。这 6 分钟内的总订单数量为 (0 + 2 + 4 + 6 + 1 + 4) = 17。
- 区间号 2 包括从 7 到 12 分钟的时间。这 6 分钟内的总订单数量为 (1 + 2 + 4 + 1 + 4 + 6) = 18。
按升序顺序返回结果表,按 interval_no 排序。

解法

方法一:按区间分组

思考

区间按分钟的取值划分, \(1\) 到 \(6\) 为区间 \(1\), \(7\) 到 \(12\) 为区间 \(2\)。六行窗口默认分钟从 \(1\) 起连续,并且每一段的右端落在 \(6\) 的倍数上。一旦出现空缺,或这一段并不以 \(6\) 的倍数结束,窗口就会漏掉区间,或把相邻区间加在一起。

\(\lfloor (minute+5)/6 \rfloor\) 把每个分钟送进所属区间。按这个值分组并对 order_count 求和,得到该区间的订单总数,再按区间号升序输出。

按 \(\lfloor (minute + 5) / 6 \rfloor\) 把每分钟划入对应区间,再对区间内的 order_count 求和,并按区间号升序输出。

1
2
3
4
5
6
7
# Write your MySQL query statement below
SELECT
    (minute + 5) DIV 6 AS interval_no,
    SUM(order_count) AS total_orders
FROM Orders
GROUP BY 1
ORDER BY 1;

方法二

思考

窗口函数仍要扫描前缀。minute 连续时可用 \(\lfloor(minute+5)/6\rfloor\) 直接分组,组内 SUM 即为该区间订单数,写法更短。

1
2
3
4
5
6
SELECT
    FLOOR((minute + 5) / 6) AS interval_no,
    SUM(order_count) AS total_orders
FROM Orders
GROUP BY 1
ORDER BY 1;

评论