SQL Server:如何排序和比较许多版本?

时间:2019-02-25 10:37:42

标签: sql sql-server versioning

在我对表的请求中,我必须查找所有版本小于或等于10.0.1703(<= 10.0.1703)且版本很多的行。我使用SQL Server。  结果中需要的行示例如下:

enter image description here

id | name | build(version)
--------------------------
1  | A    | 10.0.1703
2  | B    | 6.3.9600

我必须找到所有早于或等于10.0.1703的版本。 6.3.9600小于10.0.1703

它与此问题有关,但是提供的解决方案对我来说很难理解 How to compare software versions using SQL Server?

2 个答案:

答案 0 :(得分:5)

一种方法是将其强制转换为hierarchyid

WHERE CAST('/' + build + '/' AS HIERARCHYID) <= CAST('/10.0.1703/' AS HIERARCHYID) 

DEMO

答案 1 :(得分:0)

我同意@Larnu,如果您打算将其用于比较而不是仅仅用于显示,则最好拆分这些值并分别存储。

但是,鉴于您所拥有的,无论哪种情况,您都仍然必须具有确定更大或更小的逻辑。我喜欢PARSENAME(),然后您可以为该版本建立一个数值,类似于为IP地址创建数值。

给出此表和数据:

CREATE TABLE #x(id int NOT NULL, name char(1), build varchar(32));    

INSERT #x VALUES(1,'A','10.0.1703'),(2,'B','6.3.9600');

我们可以这样编写查询(嵌套CTE只是为了避免多次运行PARSENAME()逻辑):

DECLARE @criteria varchar(32) = '10.0.1703';

;WITH x AS
(
  SELECT id, name, build FROM #x
  UNION ALL 
  SELECT id = NULL, name = NULL, build = @criteria
),
y AS
(
  SELECT id, name, build,
    bn = PARSENAME(build,3)*10000000 + PARSENAME(build,2)*100000 + PARSENAME(build,1)
  FROM x
)
SELECT id, name, build FROM y 
  WHERE bn < (SELECT bn FROM y WHERE id IS NULL);

这假定:

  • 您所有的版本都来自同一产品,因此
    • 总是包含相同数量的“零件”
    • 永远不要包含字符
  • 10.0.14393 > 10.0.1703