3

I've got a varchar column that I want to sort numeric, which works great when using this trick: https://stackoverflow.com/a/5418033/1005334 (in short: ...ORDER BY Result * 1).

However, the table concerned contains results. So something like this occurs:

Result
------
DNS
DNF
1
2
3

The numbers are correctly ordered, but the DNF comes above the numbers when sorting like this. What I'd like is to have the numeric sort, but with non-numbers sorted alphabetically below the numbers. Like so:

Result
------
1
2
3
DNF
DNS

In what way can I modify the query (preferably only the ORDER BY clause) to get this result?

0

5 Answers 5

4

use LPAD

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_lpad

LPAD(yourField, 20, '0');

this will manage correct order for "varchar numeric fields" (10 will be after 2) and put strings at the end.

SqlFiddle

The second argument (20) is quite arbitrary. It should be equivalent to (or bigger then) the length of the longest string in your field.

Sign up to request clarification or add additional context in comments.

8 Comments

Clean function which seems to work, but I don't get how it does
@JohnWoo I made a mistake in the arguments order. Corrected. sqlfiddle.com/#!2/78de4/3
@RobinCastlin well, it's just add third argument('0') at the left of a string, x times (where x = second argument (20) - length of string). So if second argument is '3', 1 becomes '001' and '100' becomes '100' Then it's just a "string sort'
Looks good, but result gets odd when I add more numbers: sqlfiddle.com/#!2/66c54/1. Any ideas on that?
@kasimir as pointed, I made a mistake in the argument order, if you take the actual answer, it will work sqlfiddle.com/#!2/66c54/2
|
2
SELECT *, (Result REGEXP '^[0-9]+$') AS is_numeric
FROM table_name
ORDER BY is_numeric DESC, 
    CASE WHEN is_numeric THEN (Result + 0) ELSE Result END ASC

Comments

1

You can do that by using MySQL's REGEXP. Try this one,

SELECT *
FROM tablea
ORDER BY  IF(`Result` REGEXP '^-?[0-9]+$', 0, 1) ASC,
          `Result` ASC

SQLFiddle Demo

Comments

1

try this:

Please change your ORDER BY Clause with this:

  ORDER BY
  CASE WHEN Result REGEXP '^[0-9]+$' THEN Result*1 else 999999 END,
       Result 

This will order the numeric values first then the rest

2 Comments

@kasimir:I have ipdated my answer Plz check now
It works. But I think the LPAD solution is a bit more elegant (shorter).
0
ORDER BY CAST(`Result` AS SIGNED) DESC

this should work.

1 Comment

I had tried this one. This gives me reverse order: 3, 2, 1, DNF, DNS, I'm after 1, 2, 3, DNF, DNS.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.