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 порядок строк не гарантирован.
Проверьте себя
1. Что произойдёт при равных значениях первого ключа сортировки?
AСтроки вернутся в случайном порядке всегда
BПорядок решит следующий ключ ORDER BY, если он есть
CВозникнет ошибка
DСУБД отсортирует по первичному ключу автоматически
2. Куда в SQLite попадают NULL при ORDER BY val ASC?
AВ конец
BВ начало
CУдаляются
DВ случайные позиции
3. Гарантирован ли порядок строк без ORDER BY?
AДа, по порядку вставки
BДа, по первичному ключу
CНет, порядок не гарантирован
DДа, по алфавиту
Поддержать проект