Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ORDER BY ASC with Nulls at the Bottom

I'm writing an SQL query that connects a schools table to a districts table. Simple One-To-Many relationship where each school is attached to one district. My query is as follows:

SELECT 
    schools.id AS schoolid,
    schools.name AS school, 
    districts.id AS districtid, 
    districts.name AS district
FROM sms_schools AS schools
    LEFT JOIN sms_districts AS districts ON schools.districtid = districts.id
WHERE 1 = 1
ORDER BY districts.name, schools.name

The reason I did a left join is because not every school is attached to a district. For example one school may be home schooled that may contain all students that are home schooled. That wouldn't be in a district.

So what I would like to do is use the ORDER BY to order as it is by district name and then school name. The only problem is that I want the null district to be at the bottom so that I can then use a group called 'Other' at the end of my output.

Is it possible to order by ascending with nulls at the end of the output?

like image 313
Dave Long Avatar asked May 13 '11 14:05

Dave Long


People also ask

Is ORDER BY name asc displays NULLs last?

Using the ASC order, a NULL value comes before any non-NULL value; using DESC order, the NULL comes last.

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.

How is NULL treated in ORDER BY?

If you sort a column with NULL values in ascending order, the NULLs will come first. Alternatively, if you add a DESC keyword to get a descending order, NULLs will appear last.

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

Ordering. 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.


4 Answers

Only 1 minute after asking the question I found my answer. In the order by clause use case to make nulls have a higher value than anything else:

 ORDER BY (CASE WHEN districts.id IS NULL then 1 ELSE 0 END),districts.name, schools.name;
like image 165
Dave Long Avatar answered Oct 01 '22 16:10

Dave Long


You could use the ISNULL() function.

From the MySQL manual:

ISNULL(expr)

If expr is NULL, ISNULL() returns 1, otherwise it returns 0.

For example:

ORDER BY ISNULL(districts.name), districts.name, schools.name

I like to use this instead of the CASE option for MySQL. Just be aware that it's not portable since ISNULL() is not standard SQL and functions differently in other versions of SQL.

like image 27
toxalot Avatar answered Oct 01 '22 16:10

toxalot


Nulls by default occur at the top, but you can use IsNull to assign default values, that will put it in the position you require...


SELECT schools.id AS schoolid,schools.name AS school, districts.id AS districtid, districts.name AS district FROM sms_schools AS schools LEFT JOIN sms_districts AS districts ON schools.districtid = districts.id WHERE 1 = 1 
ORDER BY isnull(districts.name,'1'), schools.name 

like image 5
M.R. Avatar answered Sep 30 '22 16:09

M.R.


SELECT
 schools.id AS schoolid,
 schools.name AS school,
 districts.id AS districtid,
 districts.name AS district,
 if(schools.districtid IS NULL,1,0) as sort 
FROM sms_schools AS schools
LEFT JOIN sms_districts AS districts 
 ON schools.districtid = districts.id
WHERE 1 = 1
ORDER BY sort, districts.name, schools.name

put any more sort rules insite the 'new' colunm and use any number hide the field in your code, test if it is possebele to sort on the if dirctly(order by if...)

good luck

like image 2
borrel Avatar answered Sep 30 '22 16:09

borrel