可能重复:
如何使用 SQL Server 比较软件版本?
我是一个完整的 sql 新手,但是今天我在工作中发现了一个非常重要的 sql 查询中的错误。所以我可以使用一些帮助:
给定一个代表产品版本的 sql 字符串
'15.0.0.0'
有没有一种万无一失的方法来排序或比较该字符串,类似于.NET 类System.Version比较实例的方式?
因此,考虑到这样一个假设的构造、功能或其他任何东西,我预计“15.5.568”会大于“15.0.0.0”。
谢谢
可能重复:
如何使用 SQL Server 比较软件版本?
我是一个完整的 sql 新手,但是今天我在工作中发现了一个非常重要的 sql 查询中的错误。所以我可以使用一些帮助:
给定一个代表产品版本的 sql 字符串
'15.0.0.0'
有没有一种万无一失的方法来排序或比较该字符串,类似于.NET 类System.Version比较实例的方式?
因此,考虑到这样一个假设的构造、功能或其他任何东西,我预计“15.5.568”会大于“15.0.0.0”。
谢谢
只需添加@Gordon 的建议,这是 ParseName 的示例
; WITH tmp
AS
(
SELECT '1.0.0.5' AS Version
UNION ALL SELECT '1.5.0.06'
UNION ALL SELECT '1.0.0.06'
UNION ALL SELECT '2.0.0.0'
UNION ALL SELECT '2.0.1.1'
UNION ALL SELECT '15.15.1323.22'
UNION ALL SELECT '15.15.622.55'
)
SELECT *
FROM
(
SELECT CAST(PARSENAME(Version, 4) AS INT) AS col1
, CAST(PARSENAME(Version, 3) AS INT) AS col2
, CAST(PARSENAME(Version, 2) AS INT) AS col3
, CAST(PARSENAME(Version, 1) AS INT) AS col4
FROM tmp
) t0
ORDER BY col1, col2, col3, col4
假设 SQL Server 和已知的最大部件数,这里有一个用户定义的函数,其作用与 相同parsename
,但适用于任意数量的部件:
Create Function dbo.VersionNthPart(@version as nvarchar(max), @part as int) returns int as
Begin
Declare
@ret as int = null,
@start as int = 1,
@end as int = 0,
@partsFound as int = 0
if @version is not null
Begin
Set @ret = 0
while @partsFound < @part
Begin
Set @end = charindex('.', @version, @start)
If @end = 0
Set @partsFound = @part -- bail early
else
Begin
Set @partsFound = @partsFound + 1
If @partsFound = @part
Set @ret = Convert(int, substring(@version, @start, @end - @start))
Else
Set @start = @end + 1
End
End
End
return @ret
End
示例用法:
With
tmp
As (
Select '1.0.0.5' As Version
Union All Select '1.5.0.06'
Union All Select '1.0.0.06'
Union All Select '2.0.0.0'
Union All Select '2.0.1.1'
Union All Select '15.5.568'
Union All Select '15.0.0.0'
Union All Select '15.15.1323.22'
Union All Select '15.15.622.55'
)
Select
*
From
tmp
Order By
dbo.VersionNthPart(Version, 1),
dbo.VersionNthPart(Version, 2),
dbo.VersionNthPart(Version, 3),
dbo.VersionNthPart(Version, 4)
如果您的小数点不超过三位,那么您可以使用 parsename。以下将两个版本号校正为具有 4 个字符的值,因此字符串比较有效。你的例子是“0015.0000.0000.0000.0000”。
select (case when (right('0000'+coalesce(parsename(v1, 4), '', 4)) +
right('0000'+coalesce(parsename(v1, 3), '', 4)) +
right('0000'+coalesce(parsename(v1, 2), '', 4)) +
right('0000'+coalesce(parsename(v1, 1), '', 4))
) <
(right('0000'+coalesce(parsename(v2, 4), '', 4)) +
right('0000'+coalesce(parsename(v2, 3), '', 4)) +
right('0000'+coalesce(parsename(v2, 2), '', 4)) +
right('0000'+coalesce(parsename(v2, 1), '', 4))
)
then -1
when v1 = v2
then 0
else 1
end) as Comparison
请注意, parsename() 最多只能处理名称中的四个部分。
如果您只想排序,那么以下将起作用:
order by (right('0000'+coalesce(parsename(v1, 4), '', 4)) +
right('0000'+coalesce(parsename(v1, 3), '', 4)) +
right('0000'+coalesce(parsename(v1, 2), '', 4)) +
right('0000'+coalesce(parsename(v1, 1), '', 4))
)