3

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

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

4

3 回答 3

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;
于 2012-05-01T19:35:23.747 回答
1

真正解决这个问题的方法是根据您需要的范围将您的版本号分解为一系列smallintint或字段。bigint如果你不能这样做,那么你可能会为他们制作一个查找表,但这是一个更混乱的解决方案。

如果你有,说:

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

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

于 2012-05-01T19:35:11.433 回答
0

如果版本字符串中的数字在左侧补零,那么您可以使用字符串比较:“2.75.99.99”<“2.76.00.00”。

假设格式在所有版本中保持一致,这将起作用。

于 2012-05-01T19:50:51.767 回答