Pan*_*mar 8 sql sorting natural-sort sql-server-2008-r2
我有一个包含这样的数据的列.破折号表示同一发票的多份副本,这些副本必须按升序排序
790711
790109-1
790109-11
790109-2
Run Code Online (Sandbox Code Playgroud)
我必须按此数字按递增顺序对其进行排序,但由于这是一个varchar字段,因此按字母顺序排序
790109-1
790109-11
790109-2
790711
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,我尝试用空替换 - (破折号),然后将其作为数字投射,然后对其进行排序
select cast(replace(invoiceid,'-','') as decimal) as invoiceSort...............order by invoiceSort asc
Run Code Online (Sandbox Code Playgroud)
虽然这更好,并且这样排序
invoiceSort
790711 (790711) <-----this is wrong now as it should come later than 790109
790109-1 (7901091)
790109-2 (7901092)
790109-11 (79010911)
Run Code Online (Sandbox Code Playgroud)
有人建议我在 - (短划线)上拆分发票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
Run Code Online (Sandbox Code Playgroud)
样本数据:
InvoiceNumber
-------------
790711
790709-1
790709-11
790709-21
790709-212
790709-2
Run Code Online (Sandbox Code Playgroud)
这是代码。我有一种挥之不去的感觉,最终的表达式可以简化。
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),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber))),LEN(InvoiceNumber))
AS AffixIncludingHyphen
,SUBSTRING(InvoiceNumber,2+LEN(SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber))),LEN(InvoiceNumber))
AS AffixExcludingHyphen
,CAST(
SUBSTRING(InvoiceNumber,2+LEN(SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber))),LEN(InvoiceNumber))
AS int)
AS AffixAsInt
,REVERSE(SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber)))
AS WithoutAffix
FROM @Invoice
ORDER BY
-- WithoutAffix
REVERSE(SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber)))
-- AffixAsInt
,CAST(
SUBSTRING(InvoiceNumber,2+LEN(SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber))),LEN(InvoiceNumber))
AS int)
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
请注意,您真正需要的只是子句ORDER BY,其余的只是为了展示我的工作,如下所示:
int. 幸运的是,我们从 SQL Server 中得到了突破,因为此转换对于空字符串给出零。ORDER BY(没有任何词缀的数字),然后通过(词缀的数值)。这是我们寻求的最终命令。SUBSTRING(value, start)如果 SQL Server 允许我们从该点开始获取字符串,那么代码会更简洁,但事实并非如此,所以我们不得不说SUBSTRING(value, start, LEN(value))很多。