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

如何在Trino中按字段分组并正确获取最新语义化版本?

在Trino中处理语义化版本排序与分组取最新版本

由于Trino的MAX()聚合函数对varchar类型的版本号仅按字典序排序,无法适配语义化版本(SemVer)的规则(比如正式版本3.4.0优先级高于预发布版本3.4.0-beta.1,3.4.0-beta.11高于3.4.0-beta.2),可以通过以下两种方式解决:

方法一:手动拆分版本字段,结构化排序(无需额外插件)

如果你的Trino环境没有启用SemVer插件,可以通过字符串函数拆分版本的各个组成部分,按语义规则排序后取每组最新版本:

WITH parsed_versions AS (
    SELECT
        group_id,
        version,
        -- 拆分核心版本号(主/次/修订版),处理缺失的修订版
        CAST(split_part(split_part(version, '-', 1), '.', 1) AS INT) AS major,
        CAST(split_part(split_part(version, '-', 1), '.', 2) AS INT) AS minor,
        CAST(coalesce(split_part(split_part(version, '-', 1), '.', 3), '0') AS INT) AS patch,
        -- 提取预发布标签(如beta.1),无预发布则为空
        CASE WHEN version LIKE '%-%' THEN split_part(version, '-', 2) ELSE '' END AS pre_release,
        -- 拆分预发布标签的名称和序号,无序号则设为0
        CASE WHEN version LIKE '%-%' THEN split_part(split_part(version, '-', 2), '.', 1) ELSE '' END AS pre_tag,
        CASE WHEN version LIKE '%-%' THEN CAST(coalesce(split_part(split_part(version, '-', 2), '.', 2), '0') AS INT) ELSE 0 END AS pre_num
    FROM your_table_name
),
ranked_versions AS (
    SELECT
        group_id,
        version,
        ROW_NUMBER() OVER (
            PARTITION BY group_id
            ORDER BY
                major DESC,
                minor DESC,
                patch DESC,
                -- 正式版本(无预发布)优先于预发布版本
                CASE WHEN pre_release = '' THEN 0 ELSE 1 END ASC,
                -- 预发布标签按语义排序(alpha < beta < rc)
                pre_tag ASC,
                -- 预发布序号按数值降序(如beta.11 > beta.2)
                pre_num DESC
        ) AS version_rank
    FROM parsed_versions
)
SELECT group_id, version AS latest_semver_version
FROM ranked_versions
WHERE version_rank = 1;

说明:

  • 该方法通过将版本拆分为结构化字段,严格遵循语义化版本的排序规则:核心版本号数字越大越新,正式版本优先于所有预发布版本,预发布版本按标签字典序+序号数值排序。
  • 可以适配大部分规范的语义化版本格式,包括缺失修订版(如3.4)、多层预发布标签(如3.4.0-beta.1.2)的情况。

方法二:使用Trino SemVer插件(简洁高效)

如果你的Trino集群启用了semver插件(可通过SHOW FUNCTIONS LIKE 'semver%'验证),可以直接利用内置的语义化版本函数处理:

方式1:使用MAX_BY聚合函数

SELECT
    group_id,
    MAX_BY(version, semver_parse(version)) AS latest_semver_version
FROM your_table_name
GROUP BY group_id;

方式2:使用窗口函数排序

WITH ranked_versions AS (
    SELECT
        group_id,
        version,
        ROW_NUMBER() OVER (
            PARTITION BY group_id
            ORDER BY semver_parse(version) DESC
        ) AS version_rank
    FROM your_table_name
)
SELECT group_id, version AS latest_semver_version
FROM ranked_versions
WHERE version_rank = 1;

说明:

  • semver_parse()函数会将varchar类型的版本号转换为Trino内置的SemVer类型,该类型的排序完全遵循语义化版本规则。
  • MAX_BY(col, sort_col)聚合函数会返回sort_col取最大值时对应的col值,直接实现分组取最新版本的需求。

注意事项

  • 若使用SemVer插件,需确保版本号符合语义化版本规范(如主版本.次版本.修订版,预发布部分以-开头),否则semver_parse()会抛出错误。
  • 对于不规范的版本号,建议先清洗数据,或使用方法一的手动拆分逻辑做兼容处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:05:28