
[英]MySQL query syntax error, corresponds to your MySQL server version for the right syntax, while ordering table by name
[英]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;
substring(version, '^(\\d+)')
.. 对正则表达式模式使用substring()
进行解析。 ^
..字符串开始 ()
..捕获括号 \\d
..数字的类简写 substring(version, '^(\\d+)')::int
..转换为整数以像数字一样排序 major NULLS LAST
..版本排在最后(我的假设)。 minor NULLS FIRST
.. 2
在2.1
之前 NULLS LAST
是ORDER 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;
这将处理您评论中的所有其他规则 。
regexp_matches()
是一个功能强大的工具,但是您需要对正则表达式有基本的了解。 测试是否有疑问。
特别注意:
g
开关。 这里更多。 ()
和非捕获括号(:?)
之间的区别。 NULLIF(part[1],'')::int
..不匹配项在数组中列为空字符串。 在转换为integer
之前需要将其转换为NULL
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.