首页 > 解决方案 > 如何根据条件按组选择第一项?

问题描述

我有一个具有以下布局的表,用于存储用户的订单,并记住当前正在处理哪些订单:

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 |表示第 4 个订单是给用户 3 的,这是他/她的第 1 个订单。现在我想选择接下来要处理的订单。这必须根据以下标准进行:

所以,一段时间后,这可能看起来像这样:

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,那么我必须支持这些(按此顺序):

有任何想法吗?

标签: sqlpostgresqlgreatest-n-per-group

解决方案


我认为抓住了你的逻辑:

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;

获取一行是特定于数据库的,但其余的是非常通用的。


推荐阅读