Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Maven版本订购_Sql_Regex_Postgresql_Maven_Natural Sort - Fatal编程技术网

Sql Maven版本订购

Sql Maven版本订购,sql,regex,postgresql,maven,natural-sort,Sql,Regex,Postgresql,Maven,Natural Sort,我有一个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.a

我有一个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;

  • 子字符串(版本“^(\d+)”
    。。用于解析。
    ^
    。。字符串的开头
    ()
    。。捕获括号
    \d
    。。数字的类速记
  • 子字符串(版本“^(\d+)::int
    。。强制转换为整数以像数字一样排序
  • 。。没有数字的版本最后一个(我的假设)
  • 先将小空值
    <代码>2位于
    2.1
  • NULLS LAST
    是中的默认值,可以省略
您可以直接按顺序使用这些表达式。只是为了更好的可读性而演示

高级解决方案 对于更复杂的规则,您可能需要使用:

这涉及到

regexp\u matches()
是一个功能强大的工具,但您需要对正则表达式有基本的了解。如果有疑问,进行测试。
特别注意:

  • 不添加
    g
    开关
  • 注意捕获
    ()
    和非捕获括号
    (:?)
    之间的区别
  • NULLIF(第[1]部分)::int
    。。非匹配项在数组中列为空字符串。需要先转换为
    NULL
    ,然后才能转换为
    integer

如果版本不遵循此格式,则应将其视为字符串。
。。这并不是对它的定义。那怎么分类呢?最好添加一个具有所需排序顺序的测试用例,以避免歧义。这是真的,我在我的链接中稍微解释了定义。它说的是:“如果您的版本号与此格式不匹配,那么整个版本号将被视为限定符。”我将其解释为主版本号、次版本号和增量版本号的空值。我认为最令人惊讶的排序顺序是先排序空值,这意味着不遵循该格式的版本应该是第一个(正确格式化>正确格式化)。另一个原因是,如果反过来是真的,格式不正确的版本总是会被解释为最新的。很好的解决方案,比我最好的尝试要好得多。我可以发现的一个错误是,如果主要、次要或增量不是数字,例如,在13a.5.6-SNAPSHOT中,正则表达式将不会拾取“a”。另一个问题是,如果格式根本不正确(例如,如果版本只是一个类似“asffdgsdg”的字符串),那么它将被排在最后,这意味着它将始终被解释为最新版本(我知道这部分在我的问题中不清楚)。所以这两个都应该是第一个(正确格式化>错误格式化)@Casper:注意添加的高级解决方案。
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;