【问题标题】:Sql Server Order by nvarchar field using substring in select statementSql Server 使用 select 语句中的子字符串按 nvarchar 字段排序
【发布时间】:2013-07-29 17:54:45
【问题描述】:

我想在 select 语句中使用 Order by 子句对以下数据中的 nvarchar 字段进行排序。

1/2013
1/2014
2/2013
3/2013
5/2010
25/2013
115/2013
26/2014

我想按如下结果排序:

5/2010
1/2013
2/2013
3/2013
25/2013
115/2013
1/2014
26/2014

我正在使用以下查询,但它不起作用。

SELECT DebitNote
FROM DebitNote
ORDER BY CONVERT(
     INT, 
     SUBSTRING(debitnote, CHARINDEX('/', debitnote) + 1, 4), 
     CONVERT(INT, SUBSTRING(debitNOte, 0, CHARINDEX('/', debitNOte)))
)

【问题讨论】:

    标签: sql-server sql-server-2008 tsql


    【解决方案1】:

    试试这个 -

    DECLARE @DebitNote TABLE (DebitNote VARCHAR(50))
    
    INSERT INTO @DebitNote (DebitNote)
    VALUES 
    ('1/2013'), ('1/2014'), ('2/2013'),
    ('3/2013'), ('5/2010'),
    ('25/2013'), ('26/2014')
    
    SELECT DebitNote 
    FROM @DebitNote
    ORDER BY CAST('1/' + DebitNote AS DATETIME)
    

    输出 -

    DebitNote
    -----------------
    5/2010
    1/2013
    2/2013
    3/2013
    25/2013
    1/2014
    26/2014
    

    更新:

    DECLARE @DebitNote TABLE (DebitNote VARCHAR(50))
    INSERT INTO @DebitNote (DebitNote)
    VALUES 
         ('1/2013'), ('1/2014'),
         ('2/2013'), ('3/2013'),
         ('5/2010'), ('25/2013'),
         ('26/2014'), ('116/2013'),
         ('115/2013'), ('315/2014')
    
    SELECT DebitNote
    FROM @DebitNote
    ORDER BY 
           SUBSTRING(DebitNote, CHARINDEX('/', DebitNote) + 1, 4)
         , CONVERT(INT, SUBSTRING(DebitNote, 0, CHARINDEX('/', DebitNote)))
    

    【讨论】:

    • 我也有 115/2013、116/2013、315/2014 等值。
    【解决方案2】:

    根据经验,我编写代码的方式是我在 12 个月内不费吹灰之力就能理解的方式。同样,这意味着我希望其他开发人员也能轻松理解这件事。

    所以在这种情况下,我不会在ORDER BY 子句中隐藏这个神秘的逻辑。通过将这些值作为SELECT 子句的一部分,我会让事情变得更加透明。

    DECLARE @t table (
       DebitNote nvarchar(10)
    );
    
    INSERT INTO @t (DebitNote)
      VALUES ('1/2013')
           , ('1/2014')
           , ('2/2013')
           , ('3/2013')
           , ('5/2010')
           , ('25/2013')
           , ('115/2013')
           , ('26/2014');
    
    SELECT DebitNote
    FROM   (
            SELECT DebitNote
                 , CharIndex('/', DebitNote) As position_of_slash
                 , Cast(SubString(DebitNote, 0, CharIndex('/', DebitNote)) As int) As first_part
                 , SubString(DebitNote, CharIndex('/', DebitNote) + 1, 10) As last_part -- Note that the last parameter of the SubString() function here
                                                                                        -- equals the length of the field in question
            FROM   @t
           ) As x
    ORDER
        BY last_part
         , first_part;
    

    如果愿意,可以在 CTE 中进行最后一个查询

    ; WITH component_parts AS (
      SELECT DebitNote
           , CharIndex('/', DebitNote) As position_of_slash
           , Cast(SubString(DebitNote, 0, CharIndex('/', DebitNote)) As int) As first_part
           , SubString(DebitNote, CharIndex('/', DebitNote) + 1, 10) As last_part -- Note that the last parameter of the SubString() function here
                                                                                  -- equals the length of the field in question
      FROM   @t
    )
    SELECT DebitNote
    FROM   component_parts
    ORDER
        BY last_part
         , first_part;
    

    【讨论】:

    • gvee 你的答案不起作用,它没有像上面的输出列表那样给出想要的结果,任何工作解释都很好。
    • 尝试更新的代码(错过了将first_part 转换为int
    猜你喜欢
    • 1970-01-01
    • 2014-11-05
    • 2014-06-13
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-12
    • 2020-11-06
    相关资源
    最近更新 更多