Chapter 41: PostgreSQL ANY Operator

PostgreSQL: the ANY (and ALL) operator.

Many students see ANY for the first time and think:

“This looks weird — why not just use IN?”

And the honest answer is:

ANY is often cleaner, more flexible, and sometimes faster than IN — especially when you’re comparing against an array or a subquery result.

Let’s go step-by-step like we’re sitting together writing queries.

1. What does ANY actually do? (Plain teacher explanation)

ANY means:

“Is the left value equal to at least one value in the right-hand set (array or subquery result)?”

In other words:

SQL

is exactly the same as:

SQL

But written much more elegantly.

ALL is the opposite:

SQL

means:

“Is the left value equal to every single value in the right-hand set?”

(Almost nobody uses = ALL — usually people use NOT IN or <> ALL)

2. The three most common places you will see ANY

Pattern # Syntax example When you use it (real feeling) Equivalent (longer) form
1 column = ANY(ARRAY[1,3,5,7]) Comparing against a fixed list of values column IN (1,3,5,7)
2 column = ANY(VALUES (1),(3),(5)) Dynamic list from application / prepared statement column IN (VALUES …)
3 column = ANY(SELECT id FROM other_table …) Comparing against result of a subquery column IN (SELECT id …)

Important PostgreSQL note (2026 reality):

  • = ANY(array) is usually faster than IN (subquery) when the subquery returns many rows
  • PostgreSQL optimizer often rewrites IN (subquery) to = ANY(subquery) internally anyway
  • But writing = ANY makes your intention clearer when dealing with arrays

3. Real, practical examples (using our college schema)

Example 1: ANY with static array (most common in application code)

SQL

→ Same as e.course_id IN (1,2,3)

But now imagine the list comes from application:

SQL

→ This is very clean — no string concatenation needed

Example 2: ANY with subquery (very powerful)

SQL

→ “Higher than at least one student who actually enrolled in 2025”

Example 3: ANY vs ALL – compare extremes

SQL

→ This is very rare — most people write it as:

SQL

But > ALL is valid and sometimes clearer.

Example 4: ANY with NOT (anti-pattern – usually avoid)

SQL

→ Same as course_id NOT IN (1,2,3)

But notice:

SQL

is not the same as NOT IN when NULLs are involved — be careful.

4. ANY vs IN – when to prefer which (2026 best practice)

Situation Recommended choice Why / Performance notes
Small static list (3–10 values) IN (1,2,3) More readable
List from application array/parameter = ANY($1::int[]) Clean, no string building, safe from injection
Subquery returns many rows = ANY(subquery) Often faster than IN (subquery)
Subquery returns small number of rows IN (subquery) or = ANY Both fine — readability wins
Need to compare with every value (ALL) > ALL(subquery) or MAX MAX usually clearer

Very important performance tip:

SQL

5. Quick cheat-sheet (keep in your notes)

Goal Recommended ANY pattern More readable alternative
Match any value in fixed list status = ANY(ARRAY[‘pending’,’shipped’]) status IN (‘pending’,’shipped’)
Match any value from array parameter id = ANY($1::bigint[])
Higher than at least one value gpa > ANY(SELECT gpa FROM …) gpa > (SELECT MIN(gpa) FROM …)
Lower than every value gpa < ALL(SELECT gpa FROM …) gpa < (SELECT MAX(gpa) FROM …)
Not equal to any value course_id <> ANY(ARRAY[1,2,3]) course_id NOT IN (1,2,3)

Your mini homework right now

  1. Write query: students whose GPA is higher than at least one enrolled student in 2025 (use > ANY)
  2. Rewrite it using > (SELECT MIN(…)) → compare readability
  3. Write query using = ANY(ARRAY[…]) for students enrolled in courses 1 or 3
  4. Try NOT EXISTS vs <> ALL for students with no enrollments in a certain course

Next class?

Tell me:

  • Want ANY vs ALL vs IN performance & EXPLAIN comparison?
  • ANY inside UPDATE / DELETE?
  • How ANY works with arrays + unnest?
  • Or move to CTE, WINDOW functions, LATERAL?

Your teacher is ready — what’s the next topic? 🚀

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *