大于或小于运算符和版本

时间:2012-05-01 19:28:19

标签: sql sql-server tsql

我正在创建一个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

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

3 个答案:

答案 0 :(得分: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);

结果:

2769999

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

根据评论

编辑

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

UPDATE dbo.table SET col = col + '.00'
  WHERE LEN(x) < 10;

如果你想更精确:

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

答案 1 :(得分:1)

真正的解决方法是将您的版本号分成一系列smallintintbigint字段,具体取决于您需要的范围。如果你不能这样做,那么你可能会为它们制作一个查找表,但这是一个更麻烦的解决方案。

如果你有,请说:

CREATE TABLE Versions
(MajorVersion int,
 MinorVersion int,
 Subversion int,
 Build int)

然后您可以根据需要比较各个字段。

答案 2 :(得分:0)

如果版本字符串中的数字在左侧填零,则可以使用字符串比较:“2.75.99.99”&lt; “2.76.00.00”。

假设所有版本的格式保持一致,这将有效。