大于或小于运算符和版本

Tom*_*Tom 3 sql t-sql sql-server

我有一个我正在创建的MS SQL查询,我需要根据版本号确定特定记录是否属于"新"或"旧"类别.

有一个列'VersionNum',旧版本是2.75.99.99及以下的任何版本号,而新版本是2.76.00.00及以上的任何版本号.该列的数据类型是varchar(20).

我正在考虑从X.XX获取字符串的子集并将其转换为小数.然后,一旦所有版本都转换为X.XX十进制,我可以通过在select中的case语句中执行>或<来确定旧的或新的.

这是决定版本号落在哪里的正确或想法吗?还是有其他方法.我只是问,因为我会想象其他地方需要类似的东西,这不是一个独特的情况.

编辑:另一个问题.有些版本不是X.XX.XX.XX(2.76.00.00),有些版本的格式为:8.00.00,将被视为"旧"版本.这比我想象的要多得多.我确实得到了5位数版本(8.00.00)一直被认为是老的信息.因此,只要有5位数,版本就会过时.所以我想我会执行类似于以下的案例陈述:

SELECT
    Old = CASE WHEN LEN(VersionNum) < 10 THEN 1
               WHEN CAST(SUBSTRING(VersionNum,1,4) AS DECIMAL(5,2)) < 1.52
                    AND LEN(VersionNum) >= 10 THEN 1
               ELSE 0
          END,
    New = CASE WHEN CAST(SUBSTRING(VersionNum,1,4) AS DECIMAL(5,3)) >= 1.52
                    AND LEN(VersionNum) >= 10 THEN 1
               ELSE 0
          END
FROM
    VersionTable
Run Code Online (Sandbox Code Playgroud)

我的逻辑是否正确?或者我错过了什么.长度的不平等非常烦人.

Aar*_*and 5

您总是可以将这样的"数字"表示为整数,假设它总是只有4个部分:

DECLARE @x VARCHAR(20);

SELECT @x = '2.76.99.99';

SELECT 
 v = PARSENAME(@x, 4) * 1000000
   + PARSENAME(@x, 3) * 10000
   + PARSENAME(@x, 2) * 100
   + PARSENAME(@x, 1);
Run Code Online (Sandbox Code Playgroud)

结果:

2769999
Run Code Online (Sandbox Code Playgroud)

因此,如果您创建视图或计算列,则可以使用简单的数学进行比较,而不是尝试进行复杂的解析/转换.

根据评论编辑

如果表有一些只有三个八位字节的值,为什么不修复它?

UPDATE dbo.table SET col = col + '.00'
  WHERE LEN(x) < 10;
Run Code Online (Sandbox Code Playgroud)

如果你想更精确:

UPDATE dbo.table SET col = LTRIM(RTRIM(col)) + '.00'
  WHERE LEN(LTRIM(RTRTIM(x))) - LEN(REPLACE(LTRIM(RTRIM(x)), '.', '')) = 3;
Run Code Online (Sandbox Code Playgroud)