Comparison & conversion (Greatest, Least, NullIf, Cast, Collate, KT)

Django ORM PostgreSQL May 22, 2026 python

Greatest/Least pick across columns/values, NullIf(a, b) returns NULL when a==b, Cast changes a value's type, Collate applies a collation to one expression, and KT extracts a JSON path as text.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# ======================================================================
# `Greatest`/`Least` pick across columns/values, `NullIf(a, b)` returns NULL
# when a==b, `Cast` changes a value's type, `Collate` applies a collation to one
# expression, and `KT` extracts a JSON path as text.
# ======================================================================

# ----------------------------------------------------------------------
# Greatest / Least / Cast / KT over 'Harry Potter'
# ----------------------------------------------------------------------

# Django:
money = DecimalField(max_digits=8, decimal_places=2)
Book.objects.filter(title="Harry Potter").annotate(
    greatest=Greatest("price", Value(25), output_field=money),
    least=Least("price", Value(25), output_field=money),
    as_int=Cast("price", output_field=IntegerField()),
    stock=KT("data__specs__stock"),
).values("greatest", "least", "as_int", "stock")

# SQL:
#   SELECT GREATEST("examples_book"."price", 25) AS "greatest", LEAST("examples_book"."price", 25) AS "least", ("examples_book"."price")::integer AS "as_int", ("examples_book"."data" #>> '{specs,stock}') AS "stock"
#   FROM "examples_book"
#   WHERE "examples_book"."title" = 'Harry Potter'
#   ORDER BY "examples_book"."id" ASC
#   LIMIT 1

# Result:
#   Greatest(price, 25) -> 25
#   Least(price, 25)    -> 19.99
#   Cast(price -> int)  -> 20
#   KT(data.specs.stock)-> '12'  (json value as text)

# ----------------------------------------------------------------------
# NullIf(bio, 'British author') -> NULL when equal
# ----------------------------------------------------------------------

# Django:
Author.objects.annotate(x=NullIf("bio", Value("British author"), output_field=TextField())).values_list("name", "x")

# SQL:
#   SELECT "examples_author"."name" AS "name", NULLIF("examples_author"."bio", 'British author') AS "x"
#   FROM "examples_author"

# Result:
#   J. K. Rowling: None
#   J. R. R. Tolkien: None
#   Karl Müller: 'Schriftsteller'

# ----------------------------------------------------------------------
# Collate(name, 'C') then order by it
# ----------------------------------------------------------------------

# Django:
Author.objects.order_by(Collate("name", "C")).values_list("name", flat=True)

# SQL:
#   SELECT "examples_author"."name" AS "name"
#   FROM "examples_author"
#   ORDER BY "examples_author"."name" COLLATE "C" ASC

# Result:
#   J. K. Rowling
#   J. R. R. Tolkien
#   Karl Müller