繁体   English   中英

Maven版本订购

[英]Maven version ordering

我有一张Maven项目表。 每个项目都有许多参数和一个版本号。

当我从表中选择时,我应该只获得最高版本,但是由于Maven版本的外观,这很棘手。 这是我到目前为止的查询:

select id, group_id as group, artifact_id as artifact
from (
   select 
     p.group_id,
     p.artifact_id,
     p.id,
     rank() over (partition by p.group_id, p.artifact_id order by p.version desc)
   from projects p
   ) as ranked
   where ranked.rank = 1

由于版本不遵循字母数字顺序,因此不会提供最高版本。
版本格式在这里描述

要点是,版本可以是1.2.3-SNAPSHOT ,其中1 (大), 2 (小), 3 (增量)是数字,应按此类排序,而SNAPSHOT (限定符)是字符串。 如果版本不遵循此格式,则应将其视为字符串。

这在PostgreSQL中可行吗?

解析字符串。 喜欢:

SELECT version
      ,substring(version, '^(\d+)')::int AS major
      ,substring(version, '^\d+\.(\d+)')::int AS minor
      ,substring(version, '^\d+\.\d+\.(\d+)')::int AS incremental
      ,substring(version, '-(.+)$') AS qualifier
FROM  (
   VALUES
     ('1.2.3-SNAPSHOT')
   , ('2-FOO')
   , ('2-BAR')
   , ('2.1-BAR')
   , ('13.5.6-SNAPSHOT')
   , ('13.11.11-SNAPSHOT')
   ) x(version)
ORDER  BY major NULLS LAST
        , minor NULLS FIRST
        , incremental NULLS FIRST
        , qualifier NULLS FIRST;

-> SQLfiddle演示。

  • substring(version, '^(\\d+)') .. 对正则表达式模式使用substring()进行解析。
    ^ ..字符串开始
    () ..捕获括号
    \\d ..数字的类简写
  • substring(version, '^(\\d+)')::int ..转换为整数以像数字一样排序
  • 没有编号的major NULLS LAST ..版本排在最后(我的假设)。
  • minor NULLS FIRST .. 22.1之前
  • NULLS LASTORDER BY的默认值,可以省略。

您可以直接在ORDER BY使用这些表达式。 只是为了更好的可读性而演示。

先进的解决方案

对于更复杂的规则,您可能需要使用regexp_matches()

SELECT *, part[1] AS p1, part[2] AS p2, part[3] AS p3, part[4] AS p4
        , part[5] AS p5, part[6] AS p6, part[7] AS p7
FROM  (
   SELECT test_id, version, regexp_matches(version
           , '^(?:(\d+)(\w*)\.?(\d*)(\w*)\.?(\d*)(\w*))?(?:\-*(\w+))?') AS part
   FROM  (
      VALUES
        (1, '1.2.3-SNAPSHOT')
      , (2, '2-FOO')
      , (3, '2-BAR')
      , (4, '2.1-BAR')
      , (5, '13.5.6-SNAPSHOT')
      , (6, '13.11.11-SNAPSHOT')
      , (7, '13.11a.11-SNAPSHOT')
      , (8, '13.11b.11')
      , (9, 'Test')
      , (10, 'TEST2')
      , (11, '1a')
      , (12, '1a.1a.1a-foo')
      , (13, '1a.1a.1b-foo')
      , (14, 'sp9d8hgf')
      , (15, '2a-BAR')
      , (16, '2.1a-BAR')
      , (17, '2.1ab-BAR')
      , (18, 'incorrect1.2-foo')
      ) x(test_id, version)
   ) sub
ORDER  BY NULLIF(part[1],'')::int NULLS LAST
        , part[2] NULLS FIRST
        , NULLIF(part[3],'')::int NULLS FIRST
        , part[4] NULLS FIRST
        , NULLIF(part[5],'')::int NULLS FIRST
        , part[6] NULLS FIRST
        , part[7] NULLS FIRST;

-> SQLfiddle的

这将处理您评论中的所有其他规则

regexp_matches()是一个功能强大的工具,但是您需要对正则表达式基本的了解。 测试是否有疑问。
特别注意:

  • 不添加g开关。 这里更多。
  • 注意捕获()和非捕获括号(:?)之间的区别。
  • NULLIF(part[1],'')::int ..不匹配项在数组中列为空字符串。 在转换为integer之前需要将其转换为NULL

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM