0

I have a row that has both numbers ant strings. I whant to order it so that numbers will be ordered as numbers and all the strings would go to the end of table.

ORDER BY (
          CASE 
               WHEN `{$table}`.`{$row}` LIKE '%[^0-9]%' 
                    THEN CAST(`{$table}`.`{$row}` AS DECIMAL) 
               ELSE `{$table}`.`{$row}` 
          END
         ) ASC"

But instead the numbers are still sorted like strings.

Results: 
0
410
680
72
Some other string
Some string


It should be:
0
72
410
680
Some other string
Some string
Alexander
  • 3,129
  • 2
  • 19
  • 33
Ben
  • 3,989
  • 9
  • 48
  • 84
  • 1
    Are you sure you are using MySQL? Your `like` expression (for the intention that you have) is supported by SQL Server but not MySQL. – Gordon Linoff Feb 13 '14 at 16:31
  • I had a suspision it has something to do with like – Ben Feb 13 '14 at 16:32
  • @GordonLinoff is there a way to check if string is a number with mysql? – Ben Feb 13 '14 at 16:36
  • 1
    Yes, although you don't need that in this case because of the silent conversion (unless you want something like `'1abc'` to go with the strings. Check this out: http://stackoverflow.com/questions/75704/how-do-i-check-to-see-if-a-value-is-an-integer-in-mysql. – Gordon Linoff Feb 13 '14 at 16:45

2 Answers2

1

Try this:

order by (case when left(`{$table}`.`{$row}`, 1) between '0' and '9' then 0 else 1 end),
         `{$table}`.`{$row}` + 0,
         `{$table}`.`{$row}`

The first expression puts numbers first (or at least strings that start with a number). The second is a nice MySQL feature that simply converts a string to a number. The third sorts the non-numeric strings.

EDIT:

To have only numbers (instead of leading numbers) go first:

order by (case when left(`{$table}`.`{$row}`, 1) REGEXP '^-?[0-9]+$' then 0 else 1 end),
         `{$table}`.`{$row}` + 0,
         `{$table}`.`{$row}`
Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
0

How about the following (SQL Fiddle):

SELECT * FROM 
(
  SELECT field1
  FROM MyTable
  WHERE field1 REGEXP '^-?[0-9]+$'
  ORDER BY CAST(field1 AS DECIMAL)
  )AS m
UNION
SELECT * FROM 
(
  SELECT field1
  FROM MyTable
  WHERE field1 NOT REGEXP '^-?[0-9]+$'
  ORDER BY field1
) AS mm
Linger
  • 14,942
  • 23
  • 52
  • 79