如何在包含数字的SQL Server中对VARCHAR列进行排序?

时间:2020-03-06 14:35:08  来源:igfitidea点击:

我在" SQL Server 2000"数据库中有一个" VARCHAR"列,该列可以包含字母或者数字。这取决于在前端为客户配置应用程序的方式。

当它确实包含数字时,我希望对其进行数字排序,例如改为" 1"," 2"," 10",而不是" 1"," 10"," 2"。仅包含字母或者字母和数字(例如" A1")的字段可以按字母顺序进行排序。例如,这将是可接受的排序顺序。

1
2
10
A
B
B1

实现此目标的最佳方法是什么?

解决方案

有几种可能的方法可以做到这一点。

一个会是

SELECT
 ...
ORDER BY
  CASE 
    WHEN ISNUMERIC(value) = 1 THEN CONVERT(INT, value) 
    ELSE 9999999 -- or something huge
  END,
  value

ORDER BY的第一部分将所有内容转换为一个int(对于非数字具有巨大的价值,要排在最后),然后最后一部分负责字母。

请注意,此查询的性能在大量数据上可能至少令人讨厌。

SELECT FIELD FROM TABLE
ORDER BY 
  isnumeric(FIELD) desc, 
  CASE ISNUMERIC(test) 
    WHEN 1 THEN CAST(CAST(test AS MONEY) AS INT)
    ELSE NULL 
  END,
  FIELD

按照此链接,我们需要转换为MONEY,然后转换为INT,以避免将" $"订购为数字。

select
  Field1, Field2...
from
  Table1
order by
  isnumeric(Field1) desc,
  case when isnumeric(Field1) = 1 then cast(Field1 as int) else null end,
  Field1

这将按照我们在问题中给出的顺序返回值。

在进行所有这些转换后,性能不会太好,因此另一种方法是向表中添加另一列,在该表中存储数据的整数副本,然后按该列的顺序进行排序,然后再按该列的顺序进行排序。显然,这将需要对在表中插入或者更新数据的逻辑进行一些更改,以填充两列。或者,或者在表上放置一个触发器,以便在插入或者更新数据时填充第二列。

这似乎可行:

select your_column  
from your_table  
order by   
case when isnumeric(your_column) = 1 then your_column else 999999999 end,  
your_column

一种可能的解决方案是在数字值前面加上一个字符,以使所有字符的字符串长度相同。

这是使用该方法的示例:

select MyColumn
from MyTable
order by 
    case IsNumeric(MyColumn) 
        when 1 then Replicate('0', 100 - Len(MyColumn)) + MyColumn
        else MyColumn
    end

应将" 100"替换为该列的实际长度。