如何在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
相关产品推荐
相关产品推荐

