我有三种文物。我将这些工件存储在数据库中,并包含以下列:
artifact_type varchar2(20) not null,
artifact_version varchar2(40) not null,
artifact_blob blob default empty_blob()
版本按以下格式存储:3.0.0.0.0
有一个查询,我必须返回工件的最新版本。 max()不会为varchar返回正确的结果。那么,有没有办法找到这个版本格式的最大值,或者我应该以其他方式存储版本,还是应该再创建一个类似最新标志的列。
答案 0 :(得分:2)
这将为每个artifact_type
提供最高版本,前提是您只有数字和点(即不是3.0.2.1.1b或其他东西)。这适用于Oracle 12c
SELECT a.artifact_type, a.artifact_version, a.artifact_blob
FROM
artifacts a
WHERE a.artifact_version =
(
SELECT b.artifact_version
FROM
artifacts b
WHERE b.artifact_type = a.artifact_type
ORDER
BY CAST(REGEXP_SUBSTR(b.artifact_version,'[^.]+',1, 1) AS NUMBER) DESC,
CAST(REGEXP_SUBSTR(b.artifact_version,'[^.]+',1, 2) AS NUMBER) DESC,
CAST(REGEXP_SUBSTR(b.artifact_version,'[^.]+',1, 3) AS NUMBER) DESC,
CAST(REGEXP_SUBSTR(b.artifact_version,'[^.]+',1, 4) AS NUMBER) DESC,
CAST(REGEXP_SUBSTR(b.artifact_version,'[^.]+',1, 5) AS NUMBER) DESC
FETCH FIRST 1 ROWS ONLY
)
/
对于11g,您需要使用rownum技巧将子选择中的行集限制为仅第一行。
答案 1 :(得分:1)
作为一项常见决定,您可以使用user-defined aggregate function。
如果'最后版本'等于'最后一行插入',您可以添加一个'插入日期'列并用于订购。有时可以使用其他轻量级方法。例如,如果您可以将版本格式化为&00; 003.000.000.000',则varchar比较就足够了。
答案 2 :(得分:0)
您应该以其他格式存储版本。虽然您可以使用正则表达式来解析它,但零填充版本号可以满足您的需要。而不是3.0.0.0.0,请使用003.000.000.000.000。这更加冗长,但它允许订单和比较。
如果您知道版本总是有四个句点,那么您可以使用以下内容进行排序:
order by cast(regexp_substr(artifact_version, '[0-9]{0.}.', 1, 1) as number),
cast(regexp_substr(artifact_version, '[0-9]{0.}.', 1, 2) as number),
cast(regexp_substr(artifact_version, '[0-9]{0.}.', 1, 3) as number),
cast(regexp_substr(artifact_version, '[0-9]{0.}.', 1, 4) as number),
cast(regexp_substr(artifact_version, '[0-9]{0.}.', 1, 5) as number)
然后拉出max()
的第一个元素。
答案 3 :(得分:0)
选项1:您可以使用三个数字字段,Major,Minor,Patch来存储版本号。哪个很容易排序,但你必须得到三个字段。
选项2:将其放在不同的表格中并将其显示为视图:
Table tversion (
major NUMBER(3),
minor NUMBER(3),
patch NUMBER(3)
)
View vversion is
select major || '.' || minor || '.' || patch AS version,
major * 1000000 + minor * 1000 + patch AS sortorder from tversion;
选项3:按原样保留数据库模式,并将逻辑放在客户端以获取最大版本。