Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Natural sort for SQL Server?

I have a column that is typically only numbers (sometimes it's letters, but that's not important).

How can I make it natural sort?

Currently sorts like this: {1,10,11,12,2,3,4,5,6,7,8,9}

I want it to sort like this: {1,2,3,4,5,6,7,8,9,10,11,12}

like image 728
Malfist Avatar asked Jul 01 '10 14:07

Malfist


People also ask

What is default SQL sort?

By default, SQL Server sorts out results using ORDER BY clause in ascending order. Specifying ASC in order by clause is optional.

How do I sort A to Z in SQL?

The ORDER BY keyword is used to sort the result-set in ascending or descending order. The ORDER BY keyword sorts the records in ascending order by default. To sort the records in descending order, use the DESC keyword.

How do I create a custom sort in SQL?

By default SQL ORDER BY sort, the column in ascending order but when the descending order is needed ORDER BY DESC can be used. In case when we need a custom sort then we need to use a CASE statement where we have to mention the priorities to get the column sorted.

How do I sort 3 columns in SQL?

Syntax: SELECT * FROM table_name ORDER BY column_name; For Multiple column order, add the name of the column by which you'd like to sort records first. The column that is entered at first place will get sorted first and likewise.


2 Answers

IsNumeric is "broken", ISNUMERIC(CHAR(13)) returns 1 and CAST will fail.

Use ISNUMERIC(textval + 'e0'). Final code:

ORDER BY
  PropertyName,
  CASE ISNUMERIC(MixedField + 'e0') WHEN 1 THEN 0 ELSE 1 END, -- letters after numbers
  CASE ISNUMERIC(MixedField + 'e0') WHEN 1 THEN CAST(MixedField AS INT) ELSE 0 END,
  MixedField

You can mix order parameters...

like image 53
DiGi Avatar answered Oct 14 '22 19:10

DiGi


Cast it. Also, don't forget to use IsNumeric to make sure you only get the numbers back (if they include letters it IS important ;).

SELECT textval FROM tablename
WHERE IsNumeric(textval) = 1
ORDER BY CAST(textval as int)

Also, cast to the datatype that will hold the largest value.

If you need the non-numbers in the result set too then just append a UNION query where IsNumeric = 0 (order by whatever you want) either before or after.

like image 23
ktharsis Avatar answered Oct 14 '22 19:10

ktharsis