我有一个具有以下布局的表,用于存储用户的订单并记住当前正在处理的订单:
Sequence | User | Order | InProcess
---------+------+-------+----------
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 1 |
4 | 3 | 1 |
5 | 1 | 3 |
6 | 4 | 1 |
7 | 2 | 2 |
例如,第4 | 3 | 1 |
行表示用户3的第4个订单,这是他/她的1的订单。现在,我要选择接下来要处理的顺序。必须根据以下条件完成此操作:
InProcess
。所以,一段时间后,它看起来可能像这样:
Sequence | User | Order | InProcess
---------+------+-------+----------
1 | 1 | 1 | X
2 | 1 | 2 |
3 | 2 | 1 | X
4 | 3 | 1 | X
5 | 1 | 3 |
6 | 4 | 1 |
7 | 2 | 2 |
现在被要求下一个要处理的订单时,答案将是序列号为6的行,因为已经处理了用户1、2和3的订单,因此不能再处理其他订单。问题是:如何有效进入这一行?
基本上我需要的是与之等效的SQL
在所有订单中,选择第一个尚未处理且用户尚未处理订单的订单。
问题是如何用SQL告诉这个问题?顺便说一句:我正在寻找一种标准的SQL解决方案,而不是特定于DBMS的方法。但是,如果出于某种原因将问题限制在特定的DBMS上,那么这些就是我必须支持的(按此顺序):
有什么想法吗?
答案 0 :(得分:1)
我认为可以捕捉到您的逻辑:
select t.*
from (select t.*, max(in_process) over (partition by user_id) as any_in_process
from t
) t
where any_in_process is null
order by sequence
fetch first 1 row only;
获取一行是特定于数据库的,而其余的则是非常通用的。
答案 1 :(得分:0)
您可以使用ROW_NUMBER()
窗口函数来获取下一个要处理的订单,如下所示:
select *
from (
select
*,
row_number() over(order by "order", "sequence") as as rn
from t
where "user" not in (
select "user" from t where inprocess = 'X'
)
) x
where rn = 1
在PostgreSQL,MariaDB 10.2,MySQL 8.0,SQL Server 2012中可用。