Skip to main content
  1. About
  2. For Teams
Asked
Viewed 82k times
137

I need to sort a PostgreSQL table ascending by a date/time field, e.g. last_updated.

But that field is allowed to be empty or null and I want records with null in last_updated come before non-null last_updated.
Is this possible?

order by last_updated asc  -- and null last_updated records first ??
0

2 Answers 2

260

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, so that's effectively almost the same as just:

CREATE INDEX foo_idx ON tbl (last_updated);

For some query plans it matters where NULL values are appended. See:

Sign up to request clarification or add additional context in comments.

1 Comment

Worth noting: NULLS FIRST is default for DESC, NULLS LAST is default for ASC.
25

You can create a custom ORDER BY using a CASE statement.
The CASE statement checks for your condition and assigns to rows which meet that condition a lower value than that which is assigned to rows which do not meet the condition.
It's probably easiest to understand given an example:

  SELECT last_updated 
    FROM your_table 
ORDER BY CASE WHEN last_updated IS NULL THEN 0 ELSE 1 END, 
         last_updated ASC;

5 Comments

Also, but you probably know this, ASC is the default sorting order so you do not necessarily need to type it.
user330315
user330315
NULLS FIRST is also the ANSI compliant way to write nulls first.
@a_horse_with_no_name It's useful in my case because I want to ignore the value if it's not null, and then sort by another column instead. (Im sorting notifications — unseen first (then seenAt is null), but if seen, then I sort by createdAt instaed)
Agreed; I found this useful when just wanting to sort by whether or not a value was present (in this case, a date) — and then sorting by another value secondarily. NULLS FIRST still sorted by the actual value if the value was non-null. This did the trick for me. Thanks!
This is the best solution. Can be used with anything else like for eg deleted_at >= xyz time then 0 else 1 ...

Your Answer

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.