Sorting & limiting
Concept  ·  SQL & Querying

Default string ordering is collation-defined — binary collations sort every capital before every lowercase ('Zeb' < 'ana'); case handling is a setting, not a law.

'Alphabetical' hides a decision: binary collation compares code points, where 'Z' (90) < 'a' (97), so mixed-case directories split into a capitals section and a lowercase section — correct to the engine, absurd to the reader. Comparisons inherit the setting: WHERE name = 'ana' misses 'Ana' on binary collations and finds it on case-insensitive ones (MySQL's common default) — the same query filters differently across engines.

See it break
names
n
ana
Zeb
bo
The trap
SELECT
  n
FROM
  names
ORDER BY
  n;
The fix
SELECT
  n
FROM
  names
ORDER BY
  lower(n);
The trap
Zeb
ana
bo
The fix
ana
bo
Zeb

The surname index printed every capital before every lowercase — the default binary collation compares code points, where 'Z' (90) < 'a' (97), so 'Zeb' sorts before 'ana'; ordering by lower(n) reads alphabetically.

The rule

lower() / ILIKE at the edges; explicit collation where declared order matters; never assume the default matches the reader.

DuckDB/Postgres default case-sensitive; MySQL commonly case-insensitive — the same predicate returns different rows.

Shows up elsewhere
LIKE wildcards vs equalityNULL sort position differs by engine
Try one →Prove it in practice →