如何比较包含.NET System.Version类等版本号的SQL字符串?

时间:2012-11-09 20:47:26

标签: sql

  

可能重复:
  How to compare software versions using SQL Server?

我是一个完整且完全没有sql的新手,但是今天我在这里的sql查询中发现了一个非常重要的错误。所以我可以使用一些帮助:

给定一个代表产品版本的sql字符串

'15 .0.0.0'

是否有一种万无一失的方法来对字符串进行排序或比较,类似于.NET类System.Version如何比较实例?

所以,鉴于这样一个假设的构造,或功能或者说什么,我希望'15 .5.568'会大于'15 .0.0.0'。

由于

3 个答案:

答案 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)

http://sqlfiddle.com/#!3/e942b/3

答案 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))
         )