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

SQL如何查询pesajes表中选手最后称重accepted为0的记录

问题背景

现有存储参赛选手称重记录的pesajes表,表结构及示例数据如下:

idchampionshipcompetitoracceptedtime
118128001370931202
218128011370931784
318120301370932502
41887011370934905
518120301370961212
618110001370984288

需求是筛选指定锦标赛下,选手最后一次称重记录accepted值为0的行,以上述示例为例,期望返回id为5、6的两条记录。

原有错误查询:

SELECT * FROM pesajes WHERE championship=18 and accepted=0 GROUP by id

该语句的问题是没有判断选手后续是否存在更新的称重记录,会错误返回选手早期未通过、后续已经称重通过的记录(比如示例中id=1的记录,对应选手1280最后一次称重已通过,不属于目标结果)。

正确实现方案

方案1:通用子查询关联写法(兼容所有主流SQL版本)

核心逻辑是先定位每个选手在指定锦标赛下的最后一次称重时间,再关联回原表取对应完整记录,最后筛选accepted为0的行:

SELECT p.*
FROM pesajes p
INNER JOIN (
    -- 计算指定锦标赛下每个选手的最后一次称重时间
    SELECT competitor, MAX(time) AS last_weigh_time
    FROM pesajes
    WHERE championship = 18
    GROUP BY competitor
) t 
ON p.competitor = t.competitor AND p.time = t.last_weigh_time
WHERE p.accepted = 0;

运行该语句在示例数据下只会返回id=5、6的记录,完全匹配需求:选手1280最后一次称重accepted=1、选手870最后一次称重accepted=1,都会被正确过滤。

方案2:窗口函数写法(支持MySQL8.0+、PostgreSQL、SQL Server2005+等新版本环境)

用窗口函数按选手分组、按称重时间倒序排名,直接取每个选手排名第一的最新记录做筛选,不需要自关联,逻辑更清晰:

WITH weigh_rank AS (
    SELECT 
        *,
        ROW_NUMBER() OVER (
            PARTITION BY competitor
            ORDER BY time DESC, id DESC -- 加id倒序避免同时间戳下取错记录
        ) AS rn
    FROM pesajes
    WHERE championship = 18
)
SELECT id, championship, competitor, accepted, time
FROM weigh_rank
WHERE rn = 1 AND accepted = 0;
注意事项

如果存在同一选手同一锦标赛下多条记录time值完全相同的极端场景,不管用哪种方案,都建议把id作为次级排序/关联判断条件,确保取到最新插入的那条记录作为最后一次称重结果,避免数据重复或错漏。


内容的提问来源于stack exchange,提问作者Nebur81

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 04:57:42