【问题标题】:Sorting nvarchar column containing alphanumeric values对包含字母数字值的 nvarchar 列进行排序
【发布时间】:2011-08-06 06:37:24
【问题描述】:

我在 SQL Server 2005 表中的一列包含字母数字值,我想根据字母数字排序对行进行排序。 HOUSE_NO 是一个 NVARCHAR 列,它包含如下值:

 - 2/1 NAWOG
 - 1/1
 - 2/1 A
 - 1/2 A GOLCHA
 - 1
 - 2
 - SHASWAT KUTIR
 - 3 A
 - 11/1
 - 11

我希望它们被排序为:

 - 1
 - 1/1
 - 1/2 A GOLCHA
 - 2
 - 2/1 A
 - 2/1  NAWAG
 - 3 A
 - 11
 - 11/1
 - SHASWAT KUTIR

我尝试了很多方法,但都没有成功。我需要你的建议

【问题讨论】:

  • @zerkms: nvarchar 暗示 Oracle (AFAIK)。
  • @mu 太短:实际上不是 (mysql> create table a (b nvarchar(1)); Query OK, 0 rows affected (0.11 sec)) 但您似乎猜对了 ;-)
  • 我猜 2/2 也必须在 2/11 之前到来。让我想知道“3 A”、“3/1”和“3A”的“自然”排序顺序如何。将所有这些内容放入查询中将是一项有趣的练习,但这将是一个可怕的练习,可能具有戏剧性的表现。您应该以某种方式将此编号方案规范化为多列或添加专门用于创建排序值的列

标签: sql sql-server-2005 natural-sort


【解决方案1】:

哎呀。这不是您想要在 T-SQL 中针对大型数据集执行的操作。

DECLARE @x TABLE(HOUSE_NO NVARCHAR(32));

INSERT @x SELECT '2/1 NAWOG'
UNION ALL SELECT '1/1'
UNION ALL SELECT '2/1 A'
UNION ALL SELECT '1/2 A GOLCHA'
UNION ALL SELECT '1'
UNION ALL SELECT '2'
UNION ALL SELECT 'SHASWAT KUTIR'
UNION ALL SELECT '3 A'
UNION ALL SELECT '11/1'
UNION ALL SELECT '11';

DECLARE @n NVARCHAR(10) = N'%[^0-9]%'

SELECT HOUSE_NO FROM @x
    ORDER BY CASE 
        WHEN HOUSE_NO LIKE N'[0-9]' + @n
        THEN CONVERT(INT, SUBSTRING(HOUSE_NO, 1, PATINDEX(@n, HOUSE_NO)-1))
        WHEN HOUSE_NO NOT LIKE @n THEN CONVERT(INT, HOUSE_NO)
        ELSE 2147483647 END,
        CASE WHEN HOUSE_NO NOT LIKE @n THEN NULL
        ELSE SUBSTRING(HOUSE_NO, PATINDEX(@n, HOUSE_NO), LEN(HOUSE_NO)) END;

无论如何按门牌号排序有什么意义?

【讨论】:

  • 遗憾的是,这只是部分完成了这项工作。它采用第一部分并将所有内容转换为其数字部分。其余的种类。这忽略了这样一个事实,即在数字之后可以有更多的数字部分,如“1/11”和“1/2”。你的答案仍然指向正确的方向(理论上可以通过添加更多这种结构来解决)和 YUCK 的 +1
  • @Eddy,我已经按照操作要求的方式进行了排序。您能否编辑问题以包含一些值来演示我的解决方案在哪里出现问题,并确认该表单的值在用户系统中实际上是可能的?
  • 我的意思是我们只能解决已经提出的问题。我们也可以得出这样的结论,即存在像 'shaswat kutir/12' 这样的值,并且他希望它在没有斜杠的字符串之前排序。我不会破坏我的编码额外的假设,这只会意味着一个问题是可悲的不完整。
猜你喜欢
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 2013-10-22
  • 2021-02-22
  • 2022-11-24
  • 1970-01-01
  • 2019-02-14
  • 2016-10-28
相关资源
最近更新 更多