SQL: How can I order null and empty entries to the front in an orderby?
ORDER BY
CASE
WHEN Name IS NULL THEN 1
WHEN Name = '' THEN 2
ELSE 3
END DESC,
Name ASC
MySQL Orderby a number, Empty Strings (or 0's) Last
SELECT *
FROM tablename
WHERE visible=1
ORDER BY
case when position in('', '0') then 1 else 0 end,
position ASC,
id DESC
SQL how to make null values come last when sorting ascending
select MyDate
from MyTable
order by case when MyDate is null then 1 else 0 end, MyDate
MySql: ORDER BY ASC, Nulls at the bottom
select album from songs ORDER BY CASE WHEN album IS NULL THEN 1 WHEN album= '' THEN 2 ELSE 3 END DESC, album ASC
It will take care of empty string as well
SQL Server ORDER BY date and nulls last
smalldatetime
has range up to June 6, 2079 so you can use
ORDER BY ISNULL(Next_Contact_Date, '2079-06-05T23:59:00')
If no legitimate records will have that date.
If this is not an assumption you fancy relying on a more robust option is sorting on two columns.
ORDER BY CASE WHEN Next_Contact_Date IS NULL THEN 1 ELSE 0 END, Next_Contact_Date
Both of the above suggestions are not able to use an index to avoid a sort however and give similar looking plans.
One other possibility if such an index exists is
SELECT 1 AS Grp, Next_Contact_Date
FROM T
WHERE Next_Contact_Date IS NOT NULL
UNION ALL
SELECT 2 AS Grp, Next_Contact_Date
FROM T
WHERE Next_Contact_Date IS NULL
ORDER BY Grp, Next_Contact_Date
Sort by column ASC, but NULL values first?
Postgres has the NULLS FIRST | LAST
modifiers for ORDER BY
expression:
... ORDER BY last_updated NULLS FIRST
The typical use case is with descending sort order (DESC
), which produces the complete inversion of the default ascending order (ASC
) with null values first - which is often not desirable. To sort NULL
values last:
... ORDER BY last_updated DESC NULLS LAST
To support the query with an index, make it match:
CREATE INDEX foo_idx ON tbl (last_updated DESC NULLS LAST);
Postgres can read btree indexes backwards, but for some query plans it matters where NULL
values are appended. See:
- Performance impact of view on aggregate function vs result set limiting
How to order by column with null values last in entity framework
I would do:
using(var context = new DomainEntities())
{
var result = context.Users.OrderBy(u => u.LastName == null)
.ThenBy(u => u.LastName)
.ThenBy(u => u.FirstName == null)
.ThenBy(u => u.FirstName);
}
...which should produce reasonable SQL.
EDIT: explanation (taken from Craig's comment):
Because false
sorts before true
.
ORDER BY columns that are sometimes empty using Active Record & Rails
You're running in to a letter case problem: Your names are all capitalized, but the emails are lowercase, and with most collations, uppercase letters come before lowercase. Check out this trivial example:
#= select * from (values ('b'), ('B'), ('a'), ('A')) t (letter);
letter
--------
b
B
a
A
#= select * from (values ('b'), ('B'), ('a'), ('A')) t (letter) order by letter;
letter
--------
A
B
a
b
So your query is actually working perfectly, it's just that cxxr@person.com
sorts after Josh
. To avoid this, you can sort by the lowercase value. Here's a simple version of the data you have:
#= select * from volunteers;
first_name | last_name | email
------------+-----------+--------------------
Josh | Broger | jcool@person.com
Josh | Kenton | aj@person.com
∅ | ∅ | cxxr@person.com
Josh | Broger | broger@person.com
Alex | Diego | a.diego@person.com
Then to sort using the coalesce
you're after:
#= select * from volunteers order by lower(coalesce(first_name, email));
first_name | last_name | email
------------+-----------+--------------------
Alex | Diego | a.diego@person.com
∅ | ∅ | cxxr@person.com
Josh | Broger | broger@person.com
Josh | Broger | jcool@person.com
Josh | Kenton | aj@person.com
Or for your full version using ActiveRecord
:
Volunteer
.joins(:volunteer_lists)
.where(
"(volunteer_lists.organizer_id = ? AND organizer_type = 'Organization') OR (volunteer_lists.organizer_id IN (?) AND organizer_type = 'Collaborative')",
organization.id, collaboratives
)
.order('LOWER(COALESCE("volunteers"."first_name", "volunteers"."last_name", "volunteers"."email"))')
Possible to use SQL to sort by date but put null dates at the back of the results set?
Here's a solution using only standard SQL, not ISNULL(). That function is not standard SQL, and may not work on other brands of RDBMS.
SELECT * FROM myTable
WHERE ...
ORDER BY CASE WHEN myDate IS NULL THEN 1 ELSE 0 END, myDate;
Related Topics
Why Is My Left Join Not Returning Nulls
If Exists Statement in SQL to Linq
Ant SQL Task: How to Run SQL and Pl/Sql and Notice Execution Failure
How to Extract Certain Nth Character from a String in Sql
How to Get The First Day and The Last of Previous Month Using Sql
Oracle Pls-00363: Expression '' Cannot Be Used as an Assignment Target
Cycle Detection with Recursive Subquery Factoring
Oracle - Clone Table - Structure, Data Constraints and All
Rails Order by Association Field
SQL Split String by Space into Table in Postgresql
How to Select a Row Based on Its Row Number
If I Update a View, Will My Original Tables Get Updated
Why Are SQL Server Inserts So Slow
Sql: Get Records Created in Time Range for Specific Dates
How Much Real Storage Is Used with a Varchar(100) Declaration in MySQL