Unlike some other databases (like Oracle) PostgreSQL has a fully functional boolean
type. You can use it directly in an ORDER BY
clause without applying a CASE
statement - those are great for more complex situations.
Sort order for boolean
values is:
FALSE -> TRUE -> NULL
If you ORDER BY bool_expression
DESC
, you invert the order to:
NULL -> TRUE -> FALSE
If you want TRUE
first and NULL
last, use the NULLS LAST
clause of ORDER BY
:
ORDER BY (featured AND created_at > now() - interval '11 days') DESC NULLS LAST
, created_at DESC
Of course, NULLS LAST
is only relevant if featured
or created_at
can be NULL
. If the columns are defined NOT NULL
, then don't bother.
Also, FALSE
would be sorted before NULL
. If you don't want to distinguish between these two, you are either back to a CASE
statement, or you can throw in NULLIF()
or COALESCE()
.
ORDER BY NULLIF(featured AND created_at > now() - interval '11 days'), FALSE)
DESC NULLS LAST
, created_at DESC
Performance
Note, how I used:
created_at > now() - interval '11 days'
and not:
now() - created_at < interval '11 days'
In the first example, the expression to the right is a constant that is calculated once. Then an index can be utilized to look up matching rows. Very efficient.
The latter cannot usually be used with an index. A value has to be computed for every single row, before it can be checked against the constant expression to the right. Don't do this if you can avoid it. Ever!
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…