Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting Nulls last

Want to sort Nulls and Blanks last and have read all the solutions that use either the Coalesce function or the If in the order by column.

MY problems is non of these work for me because the column I am sorting on is specified dynamically by the PHP script that creates the query and some of my columns are in two tables in my join.

   $sortcol="boat";
   $sql= "SELECT fleet,b.boat as boat,owner FROM boats as b 
   LEFT JOIN owners as o ON  b.boat=o.boat 
   ORDER BY $sortcol";

This works great, I can change the variable $sortcol and my output listing works great except the nulls and blanks are at the top.

Based on other postings I tried this

   $sortcol="boat";
   $sql= "SELECT fleet,b.boat as boat,owner FROM boats as b 
   LEFT JOIN owners as o ON  b.boat=o.boat 
   ORDER BY IF($sortcol is NULL,1,0), $sortcol";

This throws the error "column boat in ORDER BY clause is ambiguous". Obviously it wants b.boat in the order by, but for reasons I won't get into that is problematic. It appears that anytime I try to use a function in the orderby clause I can't use the column alias.

Any ideas for an elegant solution to this??

like image 322
davewhirlwind Avatar asked Sep 30 '12 16:09

davewhirlwind


People also ask

How do you order with NULLs last?

If you specify the ORDER BY clause, NULL values by default are ordered as less than values that are not NULL. Using the ASC order, a NULL value comes before any non-NULL value; using DESC order, the NULL comes last.

When data is sorted in descending order are NULL values listed first or last?

When you order by a field that may contain NULL values, any NULLs are considered to have the lowest value. So ordering in DESC order will see the NULLs appearing last. To force NULLs to be regarded as highest values, one can add another column which has a higher value when the main field is NULL.

Which is the right answer to the following ORDER BY name asc displays NULLs last?

The answer is - SQL Server treats NULL values as the lowest values. For example when sorted in ascending order, NULLs come first.

Does group by ignore NULLs?

Group functions ignore the NULL values in the column. To enforce the group functions ti include the NULL value, use NVL function.


2 Answers

You're right. For no reason that I can fathom, MySQL accepts an ambiguous ORDER BY as long as the name you supply is not handled in any way (no way that I could think of. Maybe others exist).

As soon as it is, ambiguousness gets rejected.

This is accepted (and redundant):

select b.id, a.name as name
    FROM client AS a JOIN client AS b ON (a.id = b.id)
    ORDER BY name, name;

while COALESCE(name, ''), name IS NULL, name OR NULL are all rejected.

The obvious solution is to use a different name for the alias, one that does not appear in either table.

Another possibility would be to create a nested query:

SELECT * FROM ( your query here, without ORDER ) AS original
ORDER BY IF($sortcol is NULL,1,0), $sortcol;

That is:

$sortcol="boat";
$sql = <<<SQL
   SELECT * FROM (
      SELECT fleet,b.boat as boat,owner FROM boats as b 
         LEFT JOIN owners as o ON  b.boat=o.boat 
   ) AS original
   ORDER BY IF($sortcol is NULL,1,0), $sortcol;
SQL;
like image 143
LSerni Avatar answered Sep 28 '22 02:09

LSerni


You MUST specify the table in the ORDER BY if you have two similar column names. It's that simple.

You should be able to use a different alias in the SELECT which disambiguates from both boat columns and then use that in the

$sortcol = "bboat";
$sql= "
  SELECT 
    fleet,
    /* Alias as bboat to disambiguate from b.boat and o.boat
    b.boat as bboat,
    owner 
  FROM 
    boats as b
    LEFT JOIN owners as o ON  b.boat=o.boat 
  ORDER BY IF($sortcol is NULL,1,0), $sortcol";

Note: if $sortcol is the result of any kind of user input, it is necessary to compare it against a whitelist of acceptable column names to prevent SQL injection.

like image 44
Michael Berkowski Avatar answered Sep 28 '22 02:09

Michael Berkowski