【问题标题】:Sorting nvarchar column as integer将 nvarchar 列排序为整数
【发布时间】:2010-09-13 09:39:23
【问题描述】:

我在 nvarchar 列中有混合数据(单词和数字)。 这是按数字顺序对该列中的数据进行排序的最快方法。

结果示例:

  • 1
  • 2
  • 3
  • ...
  • 10
  • 11
  • ...
  • 啊啊啊
  • aaab
  • b
  • ...

【问题讨论】:

    标签: sql-server tsql sorting


    【解决方案1】:

    使用这个:

    ORDER BY
        CASE WHEN ISNUMERIC(column) = 1 THEN 0 ELSE 1 END,
        CASE WHEN ISNUMERIC(column) = 1 THEN CAST(column AS INT) ELSE 0 END,
        column
    

    这按预期工作。


    注意:您说最快的方式。这个 sql 对我来说生成速度很快,但执行计划显示了一个表扫描,然后是一个标量计算。这可能会产生一个临时结果,其中包含该列的所有值以及 ISNUMERIC 结果的一些额外临时列。执行起来可能不会很快。

    【讨论】:

    • 仅使用 ORDER BY CASE WHEN 1 = IsNumeric(ColumnName) THEN Cast(ColumnName AS INT) END 时会发生什么情况会更快吗?
    【解决方案2】:

    如果你用 0 填充你的数字并对其进行排序,你会得到你想要的结果。您需要确保填充的 0 的数量与 varchar 列的大小相匹配。

    看看这个例子...

    Declare @Temp Table(Data VarChar(20))
    
    Insert Into @Temp Values('1')
    Insert Into @Temp Values('2')
    Insert Into @Temp Values('3')
    Insert Into @Temp Values('10')
    Insert Into @Temp Values('11')
    Insert Into @Temp Values('aaaa')
    Insert Into @Temp Values('aaab')
    Insert Into @Temp Values('b')
    Insert Into @Temp Values('ba')
    Insert Into @Temp Values('ba')
    
    Select * From @Temp
    Order By Case When IsNumeric(Data) = 1 
                  Then Right('0000000000000000000' + Data, 20) 
                  Else Data End
    

    还要注意,在使用 case 语句时,case 语句的每个分支返回相同的数据类型很重要,否则会得到不正确的结果或错误。

    【讨论】:

      【解决方案3】:

      --检查存在
      如果存在 (select * from dbo.sysobjects where [id] = object_id(N'dbo.t') AND objectproperty(id, N'IsUserTable') = 1)
      删除表 dbo.t

      --创建示例表
      创建表 dbo.t (c varchar(10) not null)
      设置 nocount

      --填充示例表
      插入 dbo.t (c) 值 ('1')
      插入 dbo.t (c) 值 ('2')
      插入 dbo.t (c) 值 ('3')
      插入 dbo.t (c) 值 ('10')
      插入 dbo.t (c) 值 ('11')
      插入 dbo.t (c) 值 ('aaaa')
      插入 dbo.t (c) 值 ('aaab')
      插入 dbo.t (c) 值 ('b')
      插入 dbo.t (c) 值 ('ba')
      插入 dbo.t (c) 值 ('ba')

      --返回数据
      从 dbo.t 中选择 c
      isumeric(c) = 1 then 0 else 1 end,
      isumeric(c) = 1 然后 cast(c as int) else 0 end,
      c

      【讨论】:

      • 有人投了反对票。但没有留下一个理由。这是我困惑的正确解决方案吗?
      【解决方案4】:

      您可以将数据视为字母数字或数字,但不能同时视为两者。我认为您尝试做的事情是不可能的,数据模型设置不正确。

      【讨论】:

        【解决方案5】:

        投射它。

        SELECT * FROM foo ORDER BY CAST(somecolumn AS int);
        

        我接触 SQL Server 已经有一段时间了,所以我的语法可能完全不正确 :)

        【讨论】:

        • 我在 nvarchar 列中有混合数据(单词和数字)
        【解决方案6】:

        我不认为你想做什么 有可能

        这个例子很好用

        SELECT * FROM TableName
        ORDER BY CASE WHEN 1 = IsNumeric(ColumnName) THEN Cast(ColumnName AS INT) END
        

        结果是:

        • 一个
        • b
        • c
        • ...
        • 1
        • 2
        • 3

        但我首先需要数字。

        【讨论】:

          【解决方案7】:

          这应该可行:

          select * from Table order by ascii(Column)
          

          【讨论】:

            猜你喜欢
            • 2015-03-30
            • 1970-01-01
            • 1970-01-01
            • 2020-11-26
            • 2018-07-22
            • 1970-01-01
            • 1970-01-01
            • 2020-09-09
            • 1970-01-01
            相关资源
            最近更新 更多