在sql server中将字符串排序为数字

前端之家收集整理的这篇文章主要介绍了在sql server中将字符串排序为数字前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个包含这样的数据的列.破折号表示同一发票的多份副本,这些副本必须按升序排序
790711
790109-1
790109-11
790109-2

我必须按此数字按递增顺序对其进行排序,但由于这是一个varchar字段,因此按字母顺序排序

790109-1
790109-11
790109-2
790711

为了解决这个问题我尝试用空替换 – (破折号),然后将其作为数字投射,然后对其进行排序

select cast(replace(invoiceid,'-','') as decimal) as invoiceSort...............order by invoiceSort asc

虽然这样更好,并且这样排序

invoiceSort
790711      (790711)   <-----this is wrong now as it should come later than 790109
790109-1    (7901091)
790109-2    (7901092)
790109-11   (79010911)

有人建议我在 – (破折号)上拆分发票ID,并在2个拆分部分上按顺序拆分

像=====> order by split1 asc,split2 asc(790109,1)

这会工作,我想,但我将如何拆分列.

互联网上的各种拆分功能是那些返回表格的功能,而在这种情况下我需要一个标量功能.

还有其他方法可以使用吗?数据显示在网格视图中,并且网格视图默认情况下不支持在2列上进行排序(我可以实现它:))因此,如果有任何更简单的方法,我会非常好.

编辑:谢谢你的所有答案.虽然每个答案都是正确的,但我选择的答案允许我将这些列合并到GridView排序中,并最小化SQL查询的因子.

解决方法

明智地使用REVERSE,CHARINDEX和SUBSTRING,可以得到我们想要的东西.我在下面的代码中使用了希望解释的列名称来说明正在发生的事情.

设置样本数据:

DECLARE @Invoice TABLE (
    InvoiceNumber nvarchar(10)
);

INSERT @Invoice VALUES
('790711'),('790709-1'),('790709-11'),('790709-21'),('790709-212'),('790709-2')

SELECT * FROM @Invoice

样本数据:

InvoiceNumber
-------------
790711
790709-1
790709-11
790709-21
790709-212
790709-2

这是代码.我有一种唠叨的感觉,最终的表达方式可以简化.

SELECT 
    InvoiceNumber,REVERSE(InvoiceNumber) 
        AS Reversed,CHARINDEX('-',REVERSE(InvoiceNumber)) 
        AS HyphenIndexWithinReversed,SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber)) 
        AS ReversedWithoutAffix,SUBSTRING(InvoiceNumber,1+LEN(SUBSTRING(REVERSE(InvoiceNumber),LEN(InvoiceNumber))),LEN(InvoiceNumber)) 
        AS AffixIncludingHyphen,2+LEN(SUBSTRING(REVERSE(InvoiceNumber),LEN(InvoiceNumber)) 
        AS AffixExcludingHyphen,CAST(
        SUBSTRING(InvoiceNumber,LEN(InvoiceNumber))
        AS int)  
        AS AffixAsInt,REVERSE(SUBSTRING(REVERSE(InvoiceNumber),LEN(InvoiceNumber))) 
        AS WithoutAffix
FROM @Invoice
ORDER BY
    -- WithoutAffix
    REVERSE(SUBSTRING(REVERSE(InvoiceNumber),LEN(InvoiceNumber))) 
    -- AffixAsInt,LEN(InvoiceNumber))
        AS int)

输出

InvoiceNumber Reversed   HyphenIndexWithinReversed ReversedWithoutAffix AffixIncludingHyphen AffixExcludingHyphen AffixAsInt  WithoutAffix
------------- ---------- ------------------------- -------------------- -------------------- -------------------- ----------- ------------
790709-1      1-907097   2                         907097               -1                   1                    1           790709
790709-2      2-907097   2                         907097               -2                   2                    2           790709
790709-11     11-907097  3                         907097               -11                  11                   11          790709
790709-21     12-907097  3                         907097               -21                  21                   21          790709
790709-212    212-907097 4                         907097               -212                 212                  212         790709
790711        117097     0                         117097                                                         0           790711

请注意,您实际需要的只是ORDER BY子句,其余的只是为了显示我的工作,它是这样的:

>反转字符串,找到连字符,得到连字符后的子字符串,反转该部分:这是没有任何词缀的数字
>(没有任何词缀的数字)的长度告诉我们从一开始就要删除多少个字符以获得包含连字符的词缀.删除一个额外的字符以获取数字部分,并将其转换为int.幸运的是,我们从sql Server中获得了一个突破,因为这个转换为空字符串提供了零.
>最后,有了这两个部分,我们简单的ORDER BY(没有任何词缀的数字),然后是(词缀的数值).这是我们寻求的最终订单.

如果sql Server允许我们说SUBSTRING(value,start)来获取从那一点开始的字符串,但是它没有,那么代码会更简洁,所以我们不得不说SUBSTRING(value,start,LEN(value))很多.

猜你在找的MsSQL相关文章