我是一个完整且完全没有sql的新手,但是今天我在这里的sql查询中发现了一个非常重要的错误。所以我可以使用一些帮助:
给定一个代表产品版本的sql字符串
'15 .0.0.0'
是否有一种万无一失的方法来对字符串进行排序或比较,类似于.NET类System.Version如何比较实例?
所以,鉴于这样一个假设的构造,或功能或者说什么,我希望'15 .5.568'会大于'15 .0.0.0'。
由于
答案 0 :(得分:5)
只需添加@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
答案 1 :(得分:5)
假设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)
答案 2 :(得分:2)
如果您的小数点不超过三个,则可以使用parsename。以下将两个版本号修正为具有4个字符的值,因此字符串比较为owrks。你的例子是“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))
)