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,051
  • 2
  • 18
  • 31
Ben
  • 3,569
  • 6
  • 45
  • 77
  • 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,198,228
  • 53
  • 572
  • 709
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,686
  • 23
  • 50
  • 76