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

SQL group by后取最高版本对应非空test_result值的实现方法

问题分析与实现方案

你的需求是为每个测试用例取最高版本的非空测试结果,这类需求完全可以通过SQL直接实现,不需要转移到后端代码处理,数据库层执行此类分组筛选的效率远高于拉取数据到后端遍历。

现有代码问题

你当前的SQL存在错误:GROUP BY test_id会让每个测试用例仅保留一行,窗口函数ROW_NUMBER()无法拿到所有版本的行完成排序,逻辑不成立。

正确实现方式

方案1:窗口函数实现(兼容性最好,支持所有支持窗口函数的数据库,如MySQL 8.0+、PostgreSQL、SQL Server等)

WITH ranked_valid_results AS (
    SELECT
        test_id,
        test_result,
        -- 同一测试用例下,非空结果按版本倒序排序
        ROW_NUMBER() OVER (PARTITION BY test_id ORDER BY version DESC) AS row_num
    FROM TEST_RESULT
    WHERE test_result IS NOT NULL -- 提前过滤无结果的行,减少计算量
)
SELECT 
    test_id,
    test_result AS final_result
FROM ranked_valid_results
WHERE row_num = 1; -- 取排序第一的就是最高版本的有效结果

方案2:关联子查询实现(兼容不支持窗口函数的低版本数据库)

SELECT 
    t1.test_id,
    t1.test_result AS final_result
FROM TEST_RESULT t1
INNER JOIN (
    -- 先找到每个测试用例的最高有效版本
    SELECT 
        test_id,
        MAX(version) AS max_valid_version
    FROM TEST_RESULT
    WHERE test_result IS NOT NULL
    GROUP BY test_id
) t2 ON t1.test_id = t2.test_id AND t1.version = t2.max_valid_version;

方案3:PostgreSQL 专属简化写法

如果使用PostgreSQL,可使用DISTINCT ON语法更简洁的实现:

SELECT DISTINCT ON (test_id)
    test_id,
    test_result AS final_result
FROM TEST_RESULT
WHERE test_result IS NOT NULL
ORDER BY test_id, version DESC;

特殊场景说明

如果你的版本号命名规则不是简单的v+个位数(比如出现v10这类大于v9的版本),需要额外处理版本号排序逻辑,把版本号里的数字提取出来转为数值类型排序,避免出现字符串排序下v10 < v2的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 21:42:01