2

重複の可能性:
SQL Serverを使用してソフトウェアバージョンを比較する方法は?

私は完全でまったく新しいSQLですが、今日、ここでのSQLクエリで非常に重要なエラーを見つけました。だから私はいくつかの助けを使うことができます:

製品バージョンを表すSQL文字列を指定します

'15.0.0.0'

.NETクラスSystem.Versionがインスタンスを比較する方法と同様に、その文字列を並べ替えたり比較したりするための絶対確実な方法はありますか?

したがって、そのような架空の構成、関数、またはその他を考えると、「15.5.568」は「15.0.0.0」よりも大きいと予想されます。

ありがとう

4

3 に答える 3

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
于 2012-11-09T21:03:05.497 に答える
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

于 2012-11-09T21:22:44.663 に答える
2

小数点以下が3つ以下の場合は、parsenameを使用できます。次の例では、2つのバージョン番号を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()は、名前の最大4つの部分でのみ機能することに注意してください。

並べ替えるだけの場合は、次のように機能します。

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))
         )
于 2012-11-09T21:00:29.333 に答える