Tuesday, June 3, 2008

MySQL NULL sort order

Say we have an application that keeps track of tasks that need to be completed.

A task will have a name, description and an optional expiration date.

A possible schema could look something like the following.

create_table :tasks do |t|
t.column :name, :string, :null => false
t.column :description, :text
t.column :expiration, :datetime
end


Now lets try to display all Tasks ordering by their expiration. We will just display the expiration for the sake of brevity.

>> puts Tasks.all(:order => 'expiration ASC').map(&:expiration)
nil
nil
nil
Fri June 4th 00:00:00
Sat June 5th 00:00:00


The problem here is that by default null values appear at the top of the list. How can we display this list in ASC order but null values at the bottom of the list? After scouring around for awhile I finally came across a solution. It turns out that MySQL has a way to control the sorting of NULL values by adding a '-' before the field.

>> puts Tasks.all(:order => '-expiration DESC').map(&:expiration)
Fri June 4th 00:00:00
Sat June 5th 00:00:00
nil
nil
nil


Now we can list all Tasks ordered by their expiration date with NULL values at the bottom.

No comments: