【问题标题】:How can i order by column with data "01","02","03","1","2","3" and so on in sql server如何在 sql server 中按数据“01”、“02”、“03”、“1”、“2”、“3”等按列排序
【发布时间】:2021-12-08 15:25:16
【问题描述】:

我有如下数据的 SQL 表

01  Buy-1
010 Buy-10
011 Buy-11
02  Buy-2
1   Direct-1
10  Direct-10
11  Direct-11
2   Direct-2

我想按这样的数据排序

01  Buy-1
02  Buy-2
010 Buy-10
011 Buy-11    
1   Direct-1
2   Direct-2
10  Direct-10
11  Direct-11

【问题讨论】:

  • Ack....那些前导零很痛苦。
  • 将数字存储为数字,而不是文本。
  • 不知道为什么这被否决了。 OP 发布了示例数据、所需的输出并清楚地解释了他们想要完成的任务。
  • 正如@MatBailie 所指出的,问题在于您的数据类型。字符串和数字有非常不同的排序行为。似乎你想要两者兼而有之,这永远不会很有趣。
  • 我无法控制它是的,您可以 - 您可以在导入期间对其进行转换并单独存储这些值,以便您拥有“实际”值(主要是装饰性的)和相同信息的有用版本,将使您的查询更轻松、更快捷。

标签: sql-server sql-order-by


【解决方案1】:

这需要对字符串进行一些额外处理才能获得正确的排序标准。

假设您的数据与带有连字符后跟数字的示例数据一致,您可以按连字符左侧的数据排序,然后将第一列转换为 int

select id, data
from t
order by Left(data, nullif(CharIndex('-',data),0)-1),
  Try_Cast(id as int)

【讨论】:

    【解决方案2】:

    这是一个有趣的问题,我不得不回来寻找解决这个问题的方法,因为多年来已经多次出现。当您没有前导零时,这是一个相当简单的解决方案,但这是不同的。

    这适用于您的示例数据,甚至适用于我尝试过的一些极端情况。排序首先有效地计算前导零的数量,并将前导零最多的数移到顶部。然后它通过将值转换为 int 来排序。这允许您有超过 1 个前导零,并且仍然可以正确排序。此外,即使您在第一列中有字符数据,它也可以工作。

    declare @Something table
    (
        SomeValue varchar(10)
        , SomeOtherValue varchar(30)
    )
    
    insert @Something
    select '01' , 'Buy-1' union all
    select '010', 'Buy-10' union all
    select '011', 'Buy-11' union all
    select '02', 'Buy-2' union all
    select '1', 'Direct-1' union all
    select '10', 'Direct-10' union all
    select '11', 'Direct-11' union all
    select '2', 'Direct-2'
    
    select *
    from @Something s
    order by len(SomeValue) - len(convert(varchar(10), try_convert(int, SomeValue))) desc
        , try_convert(int, SomeValue)
    

    【讨论】:

    • 我希望有必要按 SomeOtherValue 中的第一个“单词”排序,然后按数值(数字)。
    • @MatBailie 实际上在这种情况下你会这样做。第一个 order by 会将前导零排序到列表的顶部。否则,前导零将被忽略。
    【解决方案3】:

    我将首先按您的代码前导零排序,其次按代码值本身。

    select code, description
    from MyTable
    order by case when left(code,1) = '0' then 0 else 1 end,
             convert(int, code)
    

    【讨论】:

      【解决方案4】:

      编号:01
      _价值:买1

      SELECT Id, _Value from tblName order by left(_Value, CHARINDEX('-', _Value)), cast(SUBSTRING(_Value, PATINDEX('%[0-9]%', _Value),len(_Value)) as int)
      

      【讨论】:

      • 这不太行。它将返回作为字符串排序的值。所以你会得到 1, 10, 11, 2
      • 谢谢。你说的对。我添加了 cast(val, as int)。你可以试试……
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-12
      • 2014-12-28
      • 1970-01-01
      • 1970-01-01
      • 2017-12-16
      • 1970-01-01
      • 2018-02-03
      相关资源
      最近更新 更多