views:

120

answers:

7

I'm busy writing a PHP app that gets data from a database, but I need to get the data in a certain order.

My Query looks as follows

$sql = "select id,title,type from campaigns where id=$cid order by type";

Now my problem is these are the different types 'GC','MJ','MU','MS','MW','MX','GS' and I want MX to always be select last, thus should always be at the end of the row. So the others shpould firstly be selected and then MX. I hope this makes sense.

+13  A: 

You can sort like this:

ORDER BY IF (type = 'MX', 1, 0), type
Greg
+1, Much better and more elegant solution than mine ;)
Joel Alejandro
+1 that's definitely more clever than my solution.
klausbyskov
wow .. I didn't even have the most remote clue that was possible.
Erik
+1 I knew there must be something like this but couldn't find the docs for it. Awesome!
Michal M
Solution is nice. Just watch out for large table. Doing so won't take advantage of index on TYPE column if there is one.
Yada
Could this also be done in postgres?
Roland
@Roland I don't know for sure but I think so
Greg
that won't work in postgresql: I've added an answer using CASE that should work.
davek
A: 
$sql = "select id,title,type from campaigns where id=$cid and type != 'MX' order by type 
union
select id,title,type from campaigns where id=$cid and type = 'MX'"; 
klausbyskov
A: 

How many rows are you selecting with your query? Looks like only one (I'm supposing that id is unique...) so the sort order has no effect.

Apart from that your sort order should do what it is supposed to do because alphabetically, MX will be the last in the list.

jeroen
+1  A: 
(select id,title,type from campaigns where id=$cid and type <> 'MX' order by type)
UNION
(select id,title,type from campaigns where id=$cid and type ='MX')
Yada
A: 

Others have thrown in SQL methods. Since you've also tagged this with php, I'll also point out you can use the usort function to define a custom comparison function to be used by the sorting algorithm.

 // returns 1 if lhs > rhs, returns 0 if lhs == rhs, returns -1 if lhs <rhs
 function customCompare($lhsRow, $rhsRow)
 {
     $lhsType = $lhsRow['type']
     $rhsType = $lhsRow['type']
     // special case code so that 'MX' is always > then anything (except for another MX)
     if ($lhsType == 'MX')
     {
          if ($rhsType == 'MX')
          {
               return 0;
          }
          else
          {
               return 1;
          }
     }

     // return 1 if lhs > rhs
     if ($lhsType > $rhsType)
     {
         return 1;
     }
     else if ($rhsType < $lhsType)
     {
         return -1;
     }
     else
     {
         return 0;
     }
 }

 $rows = /*perform query without ORDER*/
 usort($rows, "customCompare");
Doug T.
A: 

you may want to use UNION

SELECT id, title, type
FROM campaigns
WHERE id={$cid}
AND type != 'MX'
ORDER BY type

UNION

SELECT id, title, type
FROM campaigns
WHERE id={$cid}
AND type == 'MX'

and run it as one query.

Michal M
A: 
...
order by case when type = 'MX' then 1 else 0 end, type

would be portable to other databases (e.g. postgresql)

davek