ORDER BY и сортировка
ORDER BY: направление, сортировка по нескольким ключам, по выражению и куда попадают NULL.
ORDER BY задаёт порядок строк в результате. Без него порядок строк не гарантирован — даже если кажется «как вставляли».
Базовая сортировка и направление
По умолчанию сортировка по возрастанию (ASC). Для убывания — DESC. Можно сортировать по нескольким колонкам: сначала по первой, при равенстве — по второй.
CREATE TABLE players (
id INTEGER PRIMARY KEY,
team TEXT,
name TEXT,
score INTEGER
);
INSERT INTO players (team, name, score) VALUES
('A', 'Аня', 90),
('A', 'Борис', 90),
('B', 'Вера', 70),
('B', 'Гена', 85);
-- Сначала по команде по возрастанию, внутри команды — по очкам по убыванию
SELECT team, name, score
FROM players
ORDER BY team ASC, score DESC, name ASC;
Вывод:
A|Аня|90 A|Борис|90 B|Гена|85 B|Вера|70
В команде A у Ани и Бориса одинаковые 90 очков — порядок между ними решает третий ключ name. Без него их взаимный порядок был бы непредсказуем.
Сортировка по выражению и по номеру колонки
Сортировать можно по вычисляемому выражению и даже по порядковому номеру колонки в SELECT (хотя номер — менее читаемо):
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT,
price INTEGER,
qty INTEGER
);
INSERT INTO products (name, price, qty) VALUES
('Хлеб', 40, 3),
('Молоко',80, 2),
('Сыр', 300, 1);
SELECT name, price * qty AS stoimost
FROM products
ORDER BY stoimost DESC; -- сортируем по алиасу-выражению
Вывод:
Сыр|300 Молоко|160 Хлеб|120
Сортировка по алиасу stoimost работает, потому что ORDER BY выполняется после SELECT (помните логический порядок из первого урока).
Куда попадают NULL при сортировке
Это любят спросить. В SQLite (и стандарте) при ASC NULL идут первыми, при DESC — последними. То есть NULL считаются «меньше» любого значения.
CREATE TABLE t (id INTEGER PRIMARY KEY, val INTEGER);
INSERT INTO t (val) VALUES (3), (NULL), (1), (NULL), (2);
SELECT id, val
FROM t
ORDER BY val ASC; -- NULL окажутся в начале
Вывод:
2| 4| 3|1 5|2 1|3
Две строки с NULL встали в начало. Если нужно иначе, в SQLite/PostgreSQL есть NULLS LAST, но это диалект-зависимо; переносимый трюк — сортировать по val IS NULL, val.
Важно: без ORDER BY порядка нет
Распространённое заблуждение — «строки и так вернутся в порядке вставки или по первичному ключу». Это не гарантия: СУБД вправе вернуть строки в любом порядке (зависит от плана, индексов, версии). Нужен предсказуемый порядок — пишите ORDER BY явно.
Итог
ASC(по умолчанию) иDESCзадают направление; ключей сортировки может быть несколько.- Сортировать можно по выражению/алиасу —
ORDER BYидёт послеSELECT. - NULL при
ASCидут первыми; безORDER BYпорядок строк не гарантирован.