Раздел 33 · PostgreSQL с нуля

SELECT, WHERE, ORDER BY, LIMIT

junior~30 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Прошлый урок закончился двумя таблицами: авторы и книги. Магазину этого мало, ему нужны покупатели и заказы. В этом уроке у магазина появляется полная учебная база, и на ней мы начинаем задавать вопросы. Первый кластер про запросы открывает SELECT: как выбрать нужные колонки, отфильтровать строки, отсортировать их и показать только первую страницу.

Учебная база магазина

Все уроки кластера работают на одной базе. В песочницах она уже создана, у себя её можно развернуть этим скриптом:

CREATE TABLE authors (
  id      integer PRIMARY KEY,
  name    text NOT NULL,
  country text NOT NULL
);

CREATE TABLE books (
  id        integer PRIMARY KEY,
  title     text    NOT NULL,
  author_id integer NOT NULL REFERENCES authors (id),
  genre     text    NOT NULL,
  price     numeric(8, 2),
  pages     integer NOT NULL,
  year      integer NOT NULL
);

CREATE TABLE customers (
  id            integer PRIMARY KEY,
  name          text NOT NULL,
  city          text,
  registered_at date NOT NULL
);

CREATE TABLE orders (
  id          integer PRIMARY KEY,
  customer_id integer NOT NULL REFERENCES customers (id),
  created_at  date    NOT NULL,
  status      text    NOT NULL
);

CREATE TABLE order_items (
  order_id integer       NOT NULL REFERENCES orders (id),
  book_id  integer       NOT NULL REFERENCES books (id),
  qty      integer       NOT NULL,
  price    numeric(8, 2) NOT NULL,
  PRIMARY KEY (order_id, book_id)
);

INSERT INTO authors VALUES
  (1, 'Булгаков',   'Россия'),
  (2, 'Стругацкие', 'Россия'),
  (3, 'Гоголь',     'Россия'),
  (4, 'Бхаргава',   'США'),
  (5, 'Макконнелл', 'США'),
  (6, 'Толкин',     'Великобритания');

INSERT INTO books VALUES
  (1, 'Мастер и Маргарита', 1, 'роман',      690.00,  480, 1967),
  (2, 'Собачье сердце',     1, 'повесть',    390.00,  160, 1987),
  (3, 'Пикник на обочине',  2, 'фантастика', 450.00,  224, 1972),
  (4, 'Трудно быть богом',  2, 'фантастика', 520.00,  256, 1964),
  (5, 'Шинель',             3, 'повесть',    250.00,   64, 1842),
  (6, 'Мёртвые души',       3, 'роман',      610.00,  352, 1842),
  (7, 'Грокаем алгоритмы',  4, 'учебник',    1290.00, 288, 2016),
  (8, 'Совершенный код',    5, 'учебник',    2490.00, 896, 1993),
  (9, 'Нос',                3, 'повесть',    NULL,     48, 1836);

INSERT INTO customers VALUES
  (1, 'Ольга',    'Москва', '2025-11-02'),
  (2, 'Павел',    'Казань', '2026-01-15'),
  (3, 'Роман',    'Москва', '2026-03-08'),
  (4, 'Светлана', NULL,     '2026-05-20');

INSERT INTO orders VALUES
  (1, 1, '2026-09-01', 'delivered'),
  (2, 1, '2026-09-14', 'delivered'),
  (3, 2, '2026-09-20', 'shipped'),
  (4, 3, '2026-10-01', 'new'),
  (5, 2, '2026-10-05', 'cancelled');

INSERT INTO order_items VALUES
  (1, 1, 1, 690.00),  (1, 7, 1, 1290.00),
  (2, 3, 2, 450.00),
  (3, 8, 1, 2490.00), (3, 5, 1, 250.00),
  (4, 1, 1, 690.00),  (4, 4, 1, 520.00),
  (5, 6, 1, 610.00);

Пять таблиц:

  • authors авторы и их страна;
  • books книги: автор, жанр, цена, число страниц, год издания;
  • customers покупатели с городом и датой регистрации;
  • orders заказы: кто и когда купил, в каком статусе заказ;
  • order_items строки заказа: какая книга, сколько штук и по какой цене.

В данных есть несколько неудобных мест, и сделано это нарочно. У Толкина нет ни одной книги в магазине. У книги «Нос» ещё нет цены. «Собачье сердце» и «Нос» никто не заказывал. У покупательницы Светланы не указан город, и заказов у неё нет. Один заказ отменён. На таких местах запросы и ломаются, поэтому мы будем к ним возвращаться.

Запрос как заказ в библиотеке

Вспомни библиотеку с закрытым фондом из первого урока. Ты заполняешь бланк заказа: «Принесите из каталога книг названия и цены. Только фантастику. Самые дорогие сверху. Не больше трёх». Библиотекарь не спрашивает, как искать: он сам знает, где полки и какой путь короче. Ты описываешь, что хочешь получить.

SELECT и есть такой бланк. Каждая строчка бланка это отдельное предложение запроса:

SELECT title, price          -- какие колонки показать
FROM books                   -- из какой таблицы
WHERE genre = 'фантастика'   -- какие строки оставить
ORDER BY price DESC          -- как отсортировать
LIMIT 3;                     -- сколько строк вернуть

Порядок предложений в тексте строгий: SELECT, FROM, WHERE, ORDER BY, LIMIT. Переставить их нельзя, PostgreSQL ответит синтаксической ошибкой. Дальше разберём каждое по очереди.

урок из курса

Урок из курса «PostgreSQL с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.