Sql 如何根据条件分组选择第一项?
我有一个具有以下布局的表,用于存储用户订单,并记住当前正在处理的订单:Sql 如何根据条件分组选择第一项?,sql,postgresql,greatest-n-per-group,Sql,Postgresql,Greatest N Per Group,我有一个具有以下布局的表,用于存储用户订单,并记住当前正在处理的订单: Sequence | User | Order | InProcess ---------+------+-------+---------- 1 | 1 | 1 | 2 | 1 | 2 | 3 | 2 | 1 | 4 | 3 | 1 | 5 | 1 | 3 | 6 |
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的,这是他/她的第一个订单。现在我想选择下一步要处理的订单。这必须根据以下标准进行:
- 较旧的订单(序列号较低)首先处理
- 每个用户一次只处理一个订单
- 一旦订单被选择为正在处理,它将被标记为
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解决方案,而不是DBMS特有的解决方案。但是,如果出于任何原因,将问题限制在特定的DBMS上,则我必须支持这些问题(按以下顺序):
- PostgreSQL
- 马里亚布
- MySQL
- SQL Server
- 蒙哥达
有什么想法吗?我想它抓住了你的逻辑:
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;
获取一行是特定于数据库的,但其余的是相当通用的。您可以使用
row\u 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中获得。不要将保留字用作列名。它只是让每个人的生活变得复杂:顺序和顺序。这只是一个简化的例子,实际的表看起来不同。但这只是得到一般的处理顺序,它不尊重
InProcess
列,还是我遗漏了什么?@GoloRoden已根据要求修复。