Sort string as number in sql server

前端 未结 9 1487
不知归路
不知归路 2020-12-20 16:41

I have a column that contains data like this. dashes indicate multi copies of the same invoice and these have to be sorted in ascending order

790711
790109-1         


        
9条回答
  •  粉色の甜心
    2020-12-20 17:48

    One way is to split InvoiceId into its parts, and then sort on the parts. Here I use a derived table, but it could be done with a CTE or a temporary table as well.

    select InvoiceId, InvoiceId1, InvoiceId2
    from
    (
        select
        InvoiceId,
        substring(InvoiceId, 0, charindex('-', InvoiceId, 0)) as InvoiceId1,
        substring(InvoiceId, charindex('-', InvoiceId, 0)+1, len(InvoiceId)) as InvoiceId2
        FROM Invoice
    ) tmp
    order by
    cast((case when len(InvoiceId1) > 0 then InvoiceId1 else InvoiceId2 end) as int),
    cast((case when len(InvoiceId1) > 0 then InvoiceId2 else '0' end) as int)
    

    In the above, InvoiceId1 and InvoiceId2 are the component parts of InvoiceId. The outer select includes the parts, but only for demonstration purposes - you do not need to do this in your select.

    The derived table (the inner select) grabs the InvoiceId as well as the component parts. The way it works is this:

    • When there is a dash in InvoiceId, InvoiceId1 will contain the first part of the number and InvoiceId2 will contain the second.
    • When there is not a dash, InvoiceId1 will be empty and InvoiceId2 will contain the entire number.

    The second case above (no dash) is not optimal because ideally InvoiceId1 would contain the number and InvoiceId2 would be empty. To make the inner select work optimally would decrease the readability of the select. I chose the non-optimal, more readable, approach since it is good enough to allow for sorting.

    This is why the ORDER BY clause tests for the length - it needs to handle the two cases above.

    Demo at SQL Fiddle

提交回复
热议问题