March 9, 2021
This blog is part of our Rails 6.1 series.
In PostgreSQL, when sorting output rows in descending order, columns with null values will appear first.
Let's take this example of ordering users by the number of times they have logged in.
postgres=> SELECT * from users ORDER BY login_count DESC;
name | login_count
-------------------+-------------
Johnny Silverhand | NULL
Jackie Welles | 202
V | 1
(3 rows)
This is not useful since most of the time we would want the null values to appear last.
PostgreSQL provides NULLS FIRST
and NULLS LAST
options for the ORDER BY
clause for this use case.
irb> pp User.order("login_count DESC NULLS LAST").
pluck(:name, :login_count)
(0.9 ms) SELECT "users"."name", "users"."login_count" FROM "users"
ORDER BY login_count DESC NULLS LAST
=> [["Jackie Welles", 202],
["V", 1],
["Johnny Silverhand", nil]]
In Rails 6.1, we can use the new nulls_first
or nulls_last
methods to construct the same query
using Arel.
irb> pp User.order(User.arel_table[:login_count].desc.nulls_last).
pluck(:name, :login_count)
(0.9 ms) SELECT "users"."name", "users"."login_count" FROM "users"
ORDER BY login_count DESC NULLS LAST
=> [["Jackie Welles", 202],
["V", 1],
["Johnny Silverhand", nil]]
The resulting code is slightly more verbose for this simple example. But Arel really shines when programmatically constructing complex SQL queries.
Check out this pull request for more details.
If this blog was helpful, check out our full blog archive.