Why we are missing the ANY keyword in SQL
Rethinking SQL: SELECT ANY, JOIN ANY, UPDATE ANY, DELETE ANY
A small semantic shift that makes your intent explicit: do you expect data — or not?
TL;DR
Most SQL statements hide a key assumption:
Do you expect the data to exist?
SELECT ANY, JOIN ANY, UPDATE ANY, and DELETE ANY make that expectation explicit.
ANY means: absence is acceptable.
If you expect data, say so. If you don’t, say that too.
Three small keywords. Infinite clarity.
The missing expectation
SQL silently blurs the line between “no data” and “wrong data”.
A SELECT that returns zero rows isn’t technically an error — but sometimes, it should be.
If you query configuration, or a required user profile, and nothing comes back, that’s not “empty” — that’s a logic failure.
Right now, SQL can’t express that difference.
You have to handle it in your code, check row counts, throw exceptions — boilerplate everywhere.
It’s time SQL itself said what you mean.
SELECT ANY – the tolerant query
A plain SELECT should be strict by default:
If nothing matches, that’s an error — because you expected data to exist.
When absence is acceptable, you say so explicitly:
This single distinction captures the developer’s true intent.
“ANY” means: I’m okay if this is missing.
Examples
-
Optional lookup:
SELECT ANY * FROM comments WHERE post_id = :id; -
Non-critical metadata:
SELECT ANY * FROM audit_log WHERE user_id = :id; -
Cache population: “Fetch it if it’s there, skip if not.”
SQL should express intent, not assumption
When you write SQL, you’re expressing a hypothesis:
“I believe this data exists.”
If it doesn’t — what happens?
Currently, SQL acts as if every query is tolerant. It never complains about empty results.
That’s lenient, but dangerous. Silent absence hides logic bugs.
By making SELECT strict and SELECT ANY tolerant, we bring honesty back:
-
SELECT → “Expect data. Error if none.”
-
SELECT ANY → “Maybe data. That’s fine.”
JOIN ANY – the natural outer join
Once you adopt this pattern, joins fall right into place.
This is today’s LEFT OUTER JOIN, expressed as intent, not machinery.
“Join customers if they exist. Missing rows are acceptable.”
Meanwhile, a plain JOIN remains strict:
“Only include matches. Absence means exclusion.”
It’s the same rule, consistently applied.
UPDATE ANY and DELETE ANY – idempotent operations
The same expectation logic applies to modifications.
By default, UPDATE and DELETE should fail if no rows are affected —
because it means you targeted something that didn’t exist.
But sometimes, that’s fine — maintenance scripts, cleanup jobs, cache resets.
ANY makes it intentional:
You tried. Nothing happened. No problem.
Same with updates:
Still transactional, still safe — just explicitly tolerant.
The unified philosophy
| Command | Strict default | ANY variant |
|---|---|---|
| SELECT | Error if 0 rows | Accept empty result |
| JOIN | Inner join (expect matches) | Outer join (accept missing) |
| UPDATE | Error if 0 rows updated | Skip silently |
| DELETE | Error if 0 rows deleted | Skip silently |
In every case, ANY means absence is acceptable.
This creates a consistent mental model:
-
“If I say nothing, I expect data.”
-
“If I say ANY, I accept none.”
Why it matters
Modern SQL hides intent behind silence.
You never know whether a query’s emptiness was expected or not.
With this model:
-
Code becomes self-documenting.
-
Bugs surface immediately when expectations are violated.
-
Optional behavior is clearly marked, not implied.
It’s not just syntax — it’s semantics made visible.
Backward compatibility
No existing queries break.
We’re just adding new, optional intent markers:
-
SELECT ANYis today’s tolerant select (the default behavior, made explicit). -
Plain
SELECTbecomes strict. -
JOIN ANYmaps toLEFT OUTER JOIN. -
UPDATE ANYandDELETE ANYsimply suppress “no rows” warnings. -
DELETE table(withoutFROM) is pure syntactic cleanup.
Zero surprises. Total clarity.
In one sentence
“State your expectation — not your workaround.”
That’s what SQL should have been doing all along.
Kommentarer
Send en kommentar