You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL实现:筛选指定构建任务并按base_id保留最小queue_time单行

解决方案:筛选并分组获取指定条件的构建任务

嘿,这个需求可以拆成两步来实现——先精准筛选出符合要求的pending任务,再在这些任务里按base_id提取每组中queue_time最小的那一行。下面给你两种实用的方案,适配不同的数据库版本:

方案一:用窗口函数(推荐,适合支持SQL:2003及以上的数据库,比如PostgreSQL、MySQL 8.0+、SQL Server等)

窗口函数是最简洁直观的方式,先通过CTE筛选出符合条件的任务,再给每组base_id的任务按queue_time排序,取排序第一的行:

WITH eligible_pending_tasks AS (
    SELECT 
        *,
        -- 按base_id分组,每组内按queue_time升序排,生成行号
        ROW_NUMBER() OVER (PARTITION BY base_id ORDER BY queue_time ASC) AS row_num
    FROM build_tasks
    WHERE status = 'pending'
    -- 确保当前base_id下没有in-progress的任务
    AND NOT EXISTS (
        SELECT 1
        FROM build_tasks bt_inner
        WHERE bt_inner.base_id = build_tasks.base_id
        AND bt_inner.status = 'in-progress'
    )
)
-- 只保留每组行号为1的记录(也就是queue_time最小的那行)
SELECT * EXCEPT (row_num)  -- 如果是MySQL,改成列出所有需要的列,去掉row_num
FROM eligible_pending_tasks
WHERE row_num = 1;

解释下关键部分:

  • NOT EXISTS子句用来排除那些base_id下存在in-progress任务的记录
  • ROW_NUMBER()窗口函数给每个base_id组内的任务按queue_time从小到大编号,row_num=1就是每组最早进入队列的任务

方案二:用子查询关联(兼容旧版本数据库,比如MySQL 5.x)

如果你的数据库不支持窗口函数,可以先找出每个符合条件的base_id对应的最小queue_time,再通过关联原表获取完整行数据:

SELECT bt.*
FROM build_tasks bt
INNER JOIN (
    -- 先筛选符合条件的base_id,并计算每个base_id的最小queue_time
    SELECT 
        base_id,
        MIN(queue_time) AS earliest_queue_time
    FROM build_tasks
    WHERE status = 'pending'
    AND NOT EXISTS (
        SELECT 1
        FROM build_tasks bt_inner
        WHERE bt_inner.base_id = build_tasks.base_id
        AND bt_inner.status = 'in-progress'
    )
    GROUP BY base_id
) AS min_queue_info
ON bt.base_id = min_queue_info.base_id
AND bt.queue_time = min_queue_info.earliest_queue_time
WHERE bt.status = 'pending';

这个方案的逻辑是:先通过子查询得到每个合格base_id的最早队列时间,再把这个结果和原表关联,找到对应时间的完整任务记录。

内容的提问来源于stack exchange,提问作者Jordán David Nikolov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:32:48