FCFS结合优先级的SQL查询需求:优先选高优先级无则取最小队列ID
结合优先级的FCFS队列调度SQL实现
核心查询语句(获取待处理队列项)
优先选取priority=1的记录,同优先级内按队列号(queue_no)从小到大排序;无优先级1记录时,选取queue_no最小的记录:
SELECT * FROM cashier_queue_list ORDER BY CASE WHEN priority = 1 THEN 0 ELSE 1 END, queue_no ASC LIMIT 1;
逻辑说明
- 优先级区分:通过
CASE表达式生成排序权重,将priority=1的记录标记为最高优先级(权重0),其他所有记录标记为次优先级(权重1),确保优先级1的记录始终排在最前面。 - FCFS规则:同一优先级组内,按
queue_no升序排列,保证先进入队列的记录先被处理。 - 单条返回:
LIMIT 1直接返回当前需要处理的唯一队列项。
删除已处理队列项(原子操作)
为避免并发场景下的冲突,建议使用原子化的删除操作,确保查询和删除的是同一条记录:
MySQL 写法
DELETE FROM cashier_queue_list WHERE queue_no = ( SELECT queue_no FROM ( SELECT queue_no FROM cashier_queue_list ORDER BY CASE WHEN priority = 1 THEN 0 ELSE 1 END, queue_no ASC LIMIT 1 ) AS temp_table );
嵌套子查询是为了规避MySQL不允许在DELETE语句中直接引用目标表的限制。
PostgreSQL 写法
WITH selected_queue AS ( SELECT queue_no FROM cashier_queue_list ORDER BY CASE WHEN priority = 1 THEN 0 ELSE 1 END, queue_no ASC LIMIT 1 ) DELETE FROM cashier_queue_list WHERE queue_no = (SELECT queue_no FROM selected_queue);
示例验证
根据你的场景:
- 初始队列存在
queue_no=3(priority=1)、5(priority=1)、7(priority=1)、1(priority≠1),第一次执行查询会选中3,删除后队列剩余5、7、1。 - 第二次执行查询选中
5,删除后剩余7、1。 - 第三次执行查询选中
7,删除后剩余1。 - 第四次执行查询会选中
1(无优先级1记录时取最小queue_no)。
内容的提问来源于stack exchange,提问作者Angelo
相关产品推荐
相关产品推荐

