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已根据要求修复。