sql - 如何根据条件按组选择第一项?
问题描述
我有一个具有以下布局的表,用于存储用户的订单,并记住当前正在处理哪些订单:
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 个订单。现在我想选择接下来要处理的订单。这必须根据以下标准进行:
- 首先处理较旧的订单(具有较低的序列号)。
- 每个用户一次只能处理一个订单。
- 一旦订单被选择为正在处理,它就会被标记为
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,那么我必须支持这些(按此顺序):
- PostgreSQL
- 玛丽亚数据库
- MySQL
- SQL 服务器
- MongoDB
有任何想法吗?
解决方案
我认为抓住了你的逻辑:
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;
获取一行是特定于数据库的,但其余的是非常通用的。
推荐阅读
- c# - OpenSsl 在 Windows 操作系统的 Visual Studio 中可用吗?
- c++ - 将值放入 std::vector 中的空位置
- php - 在管理产品常规框中获取 WooCommerce 产品变体属性术语
- php - 显示 WooCommerce 产品价格的自定义简码:显示零价格文本
- c# - 寻找一种方法来避免应用程序授权上的 IP 欺骗
- javascript - 例外:发送电子邮件失败:没有收件人,不知道出了什么问题
- powerbi - Power Query - 会计月开始和结束日期
- r - 如何通过R中的多列计算逻辑值?
- firebase - firebase 从 url 中删除函数名称
- parallel-processing - GNU 并行终止 HPC 上 bash 脚本中的命令