MySQL/PHP Sort with natural sort

433 views Asked by At

I writing a code to get mysql field values sorted. my filed values are as below

**downloads**
N/A
10

50
30
unlimited
N/A
70
unlimited

those are on mysql table field. i need to sort those assenting and descending like below

Assending
N/A

10
30
50
70
unlimited
unlimited


Desending
unlimited
unlimited
70
50
30
10

N/A

The space is some rows don't have data. i wrote mysql query like below

SELECT * FROM fltable  ORDER BY LENGTH(downloads), downloads DESC

But this not returns correct sort, can anyone help me with this using my sql or php solution. Thank You

4

There are 4 answers

5
juergen d On BEST ANSWER
SELECT * FROM fltable  
ORDER BY case when downloads = 'N/A' then 1
              when downloads is null then 2
              when downloads = 'unlimited' then 4
              else 3
         end DESC, 
         downloads * 1 DESC
0
kirilloid On
  • I know, this solution is very similar to another in SQL.

You can use usort to implement any logic you need.

define('DV_NA', 1);
define('DV_EMPTY', 2);
define('DV_NUM', 3);
define('DV_UNLIMITED', 4);
define('DV_OTHER', 5);

function customDloadValue($n) {
  switch($n) {
  case "N/A": return DV_NA;
  case null: case "": return DV_EMPTY;
  case "unlimited": return DV_UNLIMITED;
  default: return is_numeric($n) ? DV_NUM : DV_OTHER;
  }
}

usort($strings, function ($a, $b) {
  $av = customDloadValue($a);
  $bv = customDloadValue($b);
  if ($av != DV_NUM or $bv != DV_NUM) return $av - $bv;
  return intval($a) - intval($b)
});
0
MD SHAHIDUL ISLAM On

For assending value use:

SELECT downloads, (CASE WHEN downloads = 'N/A' THEN 0 
                        WHEN downloads = '' THEN 1 
                        WHEN downloads='unlimited' THEN 4 
                        ELSE 3 END) as rank 
       FROM fltable 
       ORDER BY rank ASC;

For desending value use:

SELECT downloads, (CASE WHEN downloads = 'N/A' THEN 0 
                        WHEN downloads = '' THEN 1 
                        WHEN downloads='unlimited' THEN 4 
                        ELSE 3 END) as rank 
       FROM fltable 
       ORDER BY rank, downloads DESC;
0
antoine On

Another similar way :

SELECT download, (download= 'N/A') boolNA, (download= '') boolBlank, 
       (download+0 > 0) boolNum, (download= '0') boolZero 
FROM table 
ORDER BY boolNA DESC, boolBlank DESC, boolZero DESC, boolNum DESC, 
         (download+0), download

That way, you can create groups to sort.

Which could result in something like :

N/A

10
30
50
70
unlimited
unlimited

Same result as above, different way. If you only have a few datatype (less than 3) that you need to group, might be easier.