排队等候电梯的人数表:
Queue:
+-----------+-------------+--------+------+
| person_id | person_name | weight | num |
+-----------+-------------+--------+------+
| 5 | Alice | 250 | 1 |
| 4 | Bob | 175 | 5 |
| 3 | Alex | 350 | 2 |
| 6 | John Cena | 400 | 3 |
| 1 | Winston | 500 | 6 |
| 2 | Marie | 200 | 4 |
+-----------+-------------+--------+------+
num
是该行中的数字。电梯能提升1000磅的重量。谁是最后一个到电梯的人?
需要sql查询。(如果可能的话没有窗口函数)
result:
+-------------+
| person_name |
+-------------+
| John Cena |
+-------------+
不带窗口函数
这很尴尬,但仍然是可能的。我将分步骤构建结果,并在此过程中进行解释。
首先将表连接到自身,其中连接条件是当前位置或更早的每个人:
SELECT *
FROM Queue q1
JOIN Queue q2 on q2.Num <= q1.Num
即使只有6行样本数据,这已经是这个计算所需的21行了,所以您可以看到为什么首选窗口函数。
现在我们可以通过q1
所需的域来GROUP
,SUM
q2
的权值:
SELECT q1.Num, q1.person_id, q1.person_name, SUM(q2.Weight) as TotalWeight
FROM Queue q1
JOIN Queue q2 on q2.Num <= q1.Num
GROUP BY q1.Num, q1.person_id, q1.person_name
接下来我们使用HAVING
子句来限制总权重。
SELECT q1.Num, q1.person_id, q1.person_name, SUM(q2.Weight) as TotalWeight
FROM Queue q1
JOIN Queue q2 on q2.Num <= q1.Num
GROUP BY q1.Num, q1.person_id, q1.person_name
HAVING SUM(q2.Weight) <= 1000
最后,我们可以排序,使我们的目标记录在第一行,并且只取第一行:
SELECT TOP 1 q1.Num, q1.person_id, q1.person_name, SUM(q2.Weight) as TotalWeight
FROM Queue q1
JOIN Queue q2 on q2.Num <= q1.Num
GROUP BY q1.Num, q1.person_id, q1.person_name
HAVING SUM(q2.Weight) <= 1000
ORDER BY Num DESC
看到它在这里工作:
https://dbfiddle.uk/?rdbms=sqlserver_2019&小提琴= 42 efb4e2e71e95dcb54d59e780267857
您没有提到特定的数据库,但查询的通用版本可能看起来像:
select person_name
from (
select *, row_number() over(order by num desc) as rn
from (
select t.*, sum(weight) over(order by num) as aw from t
) x
where aw <= 1000
) y
where rn = 1