Как делать11 октября 2026 г.8 мин чтения
SQL и PostgreSQLШаг 2 из 9

SQL с нуля: SELECT, WHERE, ORDER BY

Коротко

SELECT выбирает столбцы, FROM — таблицу, WHERE оставляет строки, для которых условие истинно, ORDER BY сортирует, а LIMIT и OFFSET отрезают нужную часть результата. Сравнение с NULL через = или <> даёт не «истину» или «ложь», а NULL, поэтому такие строки в выборку не попадают — для них есть IS NULL и IS DISTINCT FROM. Без ORDER BY порядок строк не гарантирован, поэтому LIMIT без сортировки возвращает непредсказуемый набор.

Пошаговый урокУровень: НачальныйSQLПрактика: ~45–90 мин

После материала вы сможете

  • поднять учебную базу PostgreSQL 17 в Docker и выполнять запросы в psql
  • написать SELECT с нужными столбцами, вычислениями и псевдонимами AS
  • отфильтровать строки через WHERE с AND/OR, IN, BETWEEN, LIKE/ILIKE и IS NULL и объяснить, почему = NULL ничего не находит
  • отсортировать результат ORDER BY и вывести страницу через LIMIT и OFFSET, зная порядок выполнения частей запроса

Проверено на

PostgreSQL 17 (17.11, образ postgres:17-alpine)psql 17Docker Engine 29

Сверено с документацией: 11 октября 2026 г.

Содержание
  1. 01Учебная база в одну команду
  2. 02SELECT: какие столбцы вернуть
  3. 03WHERE: сравнения, AND/OR, IN, BETWEEN
  4. 04LIKE и ILIKE: поиск по тексту
  5. 05NULL: почему = NULL не работает
  6. 06ORDER BY, LIMIT, OFFSET и порядок выполнения запроса
  7. 07Упражнения с ответами

Учебная база в одну команду

Все уроки траектории «SQL и PostgreSQL» работают на одной учебной базе небольшого интернет-магазина кофе и чая. В ней четыре таблицы, знакомые по уроку об основах баз данных: clients (клиенты), products (товары), orders (заказы) и order_items (позиции заказов). Данные вымышленные, имена и e-mail — заглушки на example.com.

Сохраните скрипт ниже в файл shop.sql. Он удаляет и заново создаёт таблицы, поэтому его можно запускать повторно: если вы что-то сломали в упражнениях, база вернётся к исходному состоянию.

shop.sql
-- Training database of an online store: clients, products, orders, order_items
-- Safe to re-run: the tables are recreated from scratch.
DROP TABLE IF EXISTS order_items, orders, products, clients;

CREATE TABLE clients (
    id         bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name       text NOT NULL,
    city       text,
    email      text UNIQUE,
    created_on date NOT NULL DEFAULT current_date
);

CREATE TABLE products (
    id       bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name     text NOT NULL,
    category text NOT NULL,
    price    numeric(10, 2) NOT NULL CHECK (price > 0),
    weight_g integer CHECK (weight_g > 0)
);

CREATE TABLE orders (
    id         bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    client_id  bigint NOT NULL REFERENCES clients (id),
    ordered_on date NOT NULL,
    status     text NOT NULL
               CHECK (status IN ('new', 'paid', 'shipped', 'cancelled')),
    promo_code text
);

CREATE TABLE order_items (
    order_id   bigint NOT NULL REFERENCES orders (id) ON DELETE CASCADE,
    product_id bigint NOT NULL REFERENCES products (id),
    quantity   integer NOT NULL CHECK (quantity > 0),
    price      numeric(10, 2) NOT NULL CHECK (price > 0),
    PRIMARY KEY (order_id, product_id)
);

INSERT INTO clients (name, city, email, created_on) VALUES
    ('Aigerim Seitova',  'Almaty',    'aigerim@example.com', '2026-06-02'), -- id 1
    ('Daniyar Akhmetov', 'Astana',    NULL,                  '2026-06-15'), -- id 2
    ('Madina Omarova',   'Almaty',    'madina@example.com',  '2026-07-01'), -- id 3
    ('Timur Kim',        'Shymkent',  'timur@example.com',   '2026-07-20'), -- id 4
    ('Aliya Bekova',     NULL,        'aliya@example.com',   '2026-08-05'), -- id 5
    ('Ruslan Ivanov',    'Almaty',    NULL,                  '2026-08-28'), -- id 6
    ('Zarina Kaliyeva',  'Karaganda', 'zarina@example.org',  '2026-09-10'), -- id 7
    ('Sergey Pak',       'Astana',    'sergey@example.com',  '2026-09-30'); -- id 8

INSERT INTO products (name, category, price, weight_g) VALUES
    ('Espresso Blend 1 kg',         'coffee',    12900, 1000), -- id 1
    ('Colombia Supremo 250 g',      'coffee',     4900,  250), -- id 2
    ('Ethiopia Yirgacheffe 250 g',  'coffee',     5600,  250), -- id 3
    ('Green Sencha 100 g',          'tea',        3200,  100), -- id 4
    ('Masala Chai 200 g',           'tea',        3800,  200), -- id 5
    ('Ceramic Mug 350 ml',          'tableware',  2500, NULL), -- id 6
    ('French Press 600 ml',         'equipment',  8900, NULL), -- id 7
    ('Hand Grinder',                'equipment', 18500, NULL), -- id 8
    ('Gift Box',                    'gifts',     15000, NULL); -- id 9

INSERT INTO orders (client_id, ordered_on, status, promo_code) VALUES
    (1, '2026-09-02', 'shipped',   NULL),       -- id 1
    (2, '2026-09-05', 'shipped',   'AUTUMN10'), -- id 2
    (1, '2026-09-14', 'paid',      NULL),       -- id 3
    (3, '2026-09-20', 'cancelled', NULL),       -- id 4
    (4, '2026-09-28', 'shipped',   NULL),       -- id 5
    (5, '2026-10-01', 'paid',      'AUTUMN10'), -- id 6
    (3, '2026-10-03', 'shipped',   NULL),       -- id 7
    (6, '2026-10-05', 'new',       NULL),       -- id 8
    (1, '2026-10-08', 'paid',      'VIP'),      -- id 9
    (2, '2026-10-09', 'new',       NULL);       -- id 10: no items yet

-- price is the price at order time: the catalogue may change, the order must not
INSERT INTO order_items (order_id, product_id, quantity, price) VALUES
    (1, 1, 1, 12900), (1, 6, 2,  2500),
    (2, 2, 2,  4900), (2, 4, 1,  3200),
    (3, 7, 1,  8900),
    (4, 8, 1, 18500),
    (5, 3, 1,  5600), (5, 5, 2,  3800), (5, 6, 1, 2500),
    (6, 1, 2, 12900),
    (7, 2, 1,  4900), (7, 3, 1,  5600),
    (8, 4, 3,  3200),
    (9, 8, 1, 18500), (9, 1, 1, 12900);
Полный скрипт учебной базы. Он же используется в уроке о JOIN и группировке.

Понадобится установленный Docker. Образ postgres:17-alpine — официальный образ PostgreSQL 17 на Alpine Linux; на момент проверки это версия 17.11. Переменная POSTGRES_PASSWORD обязательна для образа. Мы не публикуем порт через -p, поэтому база недоступна снаружи контейнера, а пароль test годится только для такого локального учебного запуска.

bash
# 1. Start PostgreSQL 17 in a container (it is removed when stopped)
docker run -d --rm --name shop-db -e POSTGRES_PASSWORD=test postgres:17-alpine

# 2. Wait a few seconds, then load the training database
#    (run from the folder that contains shop.sql)
docker exec -i shop-db psql -U postgres < shop.sql

# 3. Open psql; NULL values are printed as NULL
docker exec -it shop-db psql -U postgres -P null=NULL

Если выполнить второй шаг сразу после первого, сервер ещё может инициализироваться — тогда psql ответит ошибкой подключения. Подождите несколько секунд и повторите команду:

terminal
$ docker exec -i shop-db psql -U postgres < shop.sql
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory
	Is the server running locally and accepting connections on that socket?

В PowerShell оператор < не поддерживается, поэтому второй шаг выглядит так:

PowerShell
Get-Content shop.sql | docker exec -i shop-db psql -U postgres
terminal
$ docker exec -i shop-db psql -U postgres < shop.sql
NOTICE:  table "order_items" does not exist, skipping
NOTICE:  table "orders" does not exist, skipping
NOTICE:  table "products" does not exist, skipping
NOTICE:  table "clients" does not exist, skipping
DROP TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
INSERT 0 8
INSERT 0 9
INSERT 0 10
INSERT 0 15
Реальный вывод при первой загрузке. NOTICE — не ошибка: таблиц ещё не было, удалять нечего.

Третья команда открывает интерактивный psql. Параметр -P null=NULL просит печатать NULL словом: по умолчанию psql выводит пустоту, и документация отмечает, что её легко спутать с пустой строкой. Все результаты в уроке получены именно с этой настройкой. Команда \dt показывает таблицы, \q — выход, а docker stop shop-db останавливает и удаляет контейнер вместе с данными.

terminal
postgres=# \dt
            List of relations
 Schema |    Name     | Type  |  Owner
--------+-------------+-------+----------
 public | clients     | table | postgres
 public | order_items | table | postgres
 public | orders      | table | postgres
 public | products    | table | postgres
(4 rows)
Четыре таблицы учебной базы в psql.

SELECT: какие столбцы вернуть

Запрос SELECT состоит из списка выбора (какие столбцы вернуть), списка таблиц после FROM и необязательного условия. Звёздочка означает «все столбцы». Каждая команда SQL заканчивается точкой с запятой — без неё psql ждёт продолжения.

SQL
SELECT * FROM products;

1

name
Espresso Blend 1 kg
category
coffee
price
12900.00
weight_g
1000

2

name
Colombia Supremo 250 g
category
coffee
price
4900.00
weight_g
250

3

name
Ethiopia Yirgacheffe 250 g
category
coffee
price
5600.00
weight_g
250

4

name
Green Sencha 100 g
category
tea
price
3200.00
weight_g
100

5

name
Masala Chai 200 g
category
tea
price
3800.00
weight_g
200

6

name
Ceramic Mug 350 ml
category
tableware
price
2500.00
weight_g
NULL

7

name
French Press 600 ml
category
equipment
price
8900.00
weight_g
NULL

8

name
Hand Grinder
category
equipment
price
18500.00
weight_g
NULL

9

name
Gift Box
category
gifts
price
15000.00
weight_g
NULL
Реальный вывод psql: все девять товаров. NULL в weight_g — вес не указан.

В списке выбора можно перечислить нужные столбцы и написать выражения. AS задаёт имя столбца в результате — псевдоним. Функция round округляет число, а строка в одинарных кавычках — это литерал, одинаковый для всех строк.

SQL
SELECT name,
       price,
       round(price * 0.9) AS price_with_10_off,
       'KZT' AS currency
FROM products;

Espresso Blend 1 kg

price
12900.00
price_with_10_off
11610
currency
KZT

Colombia Supremo 250 g

price
4900.00
price_with_10_off
4410
currency
KZT

Ethiopia Yirgacheffe 250 g

price
5600.00
price_with_10_off
5040
currency
KZT

Green Sencha 100 g

price
3200.00
price_with_10_off
2880
currency
KZT
Цена со скидкой 10% вычисляется на лету, таблица products не меняется. Сокращено: показаны первые 4 строки из 9.

DISTINCT убирает повторяющиеся строки результата. Документация PostgreSQL предупреждает: DISTINCT сам по себе не сортирует, поэтому для предсказуемого порядка добавляют ORDER BY.

SQL
SELECT DISTINCT category
FROM products
ORDER BY category;

coffee

equipment

gifts

tableware

tea

Пять категорий каталога.

WHERE: сравнения, AND/OR, IN, BETWEEN

WHERE оставляет только строки, для которых логическое условие истинно. Строки, где условие ложно или равно NULL, отбрасываются. Числа пишут как есть, а строки и даты — в одинарных кавычках.

=, <>

Значение
Равно, не равно (!= — синоним <>)
Пример
status = 'paid'

<, >, <=, >=

Значение
Меньше, больше, включая равенство
Пример
price > 10000

AND, OR, NOT

Значение
И, или, не
Пример
category = 'coffee' AND price < 6000

IN (…)

Значение
Равно одному из значений списка
Пример
status IN ('paid', 'shipped')

BETWEEN a AND b

Значение
В диапазоне, границы включены
Пример
ordered_on BETWEEN '2026-09-01' AND '2026-09-30'
SQL
SELECT name, price
FROM products
WHERE price > 10000;

Espresso Blend 1 kg

price
12900.00

Hand Grinder

price
18500.00

Gift Box

price
15000.00
Товары дороже 10 000 ₸.

Главная ловушка — приоритет операторов: AND связывает сильнее, чем OR. Допустим, нужен кофе или оборудование дешевле 6000 ₸. Запрос без скобок читается базой как «кофе любой цены, или оборудование дешевле 6000»:

SQL
-- Intent: coffee or equipment cheaper than 6000
SELECT name, category, price
FROM products
WHERE category = 'coffee' OR category = 'equipment' AND price < 6000;

Espresso Blend 1 kg

category
coffee
price
12900.00

Colombia Supremo 250 g

category
coffee
price
4900.00

Ethiopia Yirgacheffe 250 g

category
coffee
price
5600.00
Ошибка: в выборку попал Espresso Blend за 12 900 ₸.
SQL
SELECT name, category, price
FROM products
WHERE (category = 'coffee' OR category = 'equipment') AND price < 6000;

Colombia Supremo 250 g

category
coffee
price
4900.00

Ethiopia Yirgacheffe 250 g

category
coffee
price
5600.00
Со скобками условие цены применяется к обеим категориям. Оборудования дешевле 6000 ₸ в каталоге нет.

IN заменяет цепочку OR по одному столбцу, а BETWEEN — пару сравнений >= и <=. Обе границы BETWEEN входят в диапазон, это отмечено в документации.

SQL
SELECT id, client_id, status
FROM orders
WHERE status IN ('paid', 'shipped');
SQL
SELECT id, ordered_on, status
FROM orders
WHERE ordered_on BETWEEN '2026-09-01' AND '2026-09-30';

1

ordered_on
2026-09-02
status
shipped

2

ordered_on
2026-09-05
status
shipped

3

ordered_on
2026-09-14
status
paid

4

ordered_on
2026-09-20
status
cancelled

5

ordered_on
2026-09-28
status
shipped
Заказы сентября 2026: пять строк, включая отменённый.

LIKE и ILIKE: поиск по тексту

LIKE сравнивает строку с шаблоном. В шаблоне % означает любую последовательность символов, в том числе пустую, а _ — ровно один любой символ. Шаблон всегда покрывает строку целиком: чтобы найти подстроку где угодно, ставят % с обеих сторон.

SQL
SELECT name FROM products WHERE name LIKE '%250 g';

Colombia Supremo 250 g

Ethiopia Yirgacheffe 250 g

Товары, название которых заканчивается на «250 g».

LIKE различает регистр. ILIKE — расширение PostgreSQL, которого нет в стандарте SQL, — сравнивает без учёта регистра по правилам текущей локали:

SQL
SELECT name FROM clients WHERE name LIKE '%ova';
SELECT name FROM clients WHERE name LIKE 'a%';
SELECT name FROM clients WHERE name ILIKE 'a%';

--       name
-- -----------------
--  Aigerim Seitova
--  Madina Omarova
--  Aliya Bekova
-- (3 rows)
--
--  name
-- ------
-- (0 rows)
--
--       name
-- -----------------
--  Aigerim Seitova
--  Aliya Bekova
-- (2 rows)
Три запроса подряд, реальный вывод — в комментариях: 'a%' не находит имён с заглавной A.

Чтобы искать сами символы % или _, их экранируют обратной косой чертой: LIKE '%\_%' найдёт строки с подчёркиванием.

NULL: почему = NULL не работает

NULL в SQL означает «значение неизвестно». Документация PostgreSQL формулирует правило так: обычные операторы сравнения дают NULL, а не «истину» или «ложь», если хотя бы один операнд равен NULL. Неизвестно, равны ли два неизвестных значения, поэтому даже NULL = NULL — это NULL.

SQL
SELECT name, email FROM clients WHERE email = NULL;

--  name | email
-- ------+-------
-- (0 rows)
Ноль строк, хотя у двух клиентов e-mail не указан.
SQL
SELECT name, email FROM clients WHERE email IS NULL;

Daniyar Akhmetov

email
NULL

Ruslan Ivanov

email
NULL
IS NULL — правильная проверка на отсутствие значения.

SQL использует трёхзначную логику: истина, ложь и NULL («неизвестно»). WHERE пропускает только «истину». Посмотрим, во что превращаются выражения с NULL:

SQL
SELECT NULL = NULL      AS null_eq_null,
       7 <> NULL        AS seven_ne_null,
       NULL IS NULL     AS null_is_null,
       true OR NULL     AS true_or_null,
       false AND NULL   AS false_and_null;

NULL

seven_ne_null
NULL
null_is_null
t
true_or_null
t
false_and_null
f
Реальный вывод: t — истина, f — ложь. TRUE OR NULL — истина при любом неизвестном, FALSE AND NULL — ложь.

Отсюда самая частая ошибка: условие «не равно» теряет строки с NULL. Нам нужны клиенты не из Алматы — Aliya Bekova, у которой город не указан, в выборку не попадёт, потому что NULL <> 'Almaty' — это NULL:

SQL
SELECT name, city FROM clients WHERE city <> 'Almaty';

Daniyar Akhmetov

city
Astana

Timur Kim

city
Shymkent

Zarina Kaliyeva

city
Karaganda

Sergey Pak

city
Astana
Четыре строки: клиентка без города потерялась.
SQL
SELECT name, city FROM clients WHERE city IS DISTINCT FROM 'Almaty';

Daniyar Akhmetov

city
Astana

Timur Kim

city
Shymkent

Aliya Bekova

city
NULL

Zarina Kaliyeva

city
Karaganda

Sergey Pak

city
Astana
IS DISTINCT FROM сравнивает NULL как обычное значение: пять строк.

Та же ловушка в NOT IN: если в списке есть NULL или проверяемое значение равно NULL, результат — NULL, а не «истина». Запрос WHERE city NOT IN ('Almaty', 'Astana') вернёт только Shymkent и Karaganda, клиентки без города в нём не будет. Документация советует по возможности формулировать условие положительно.

Для вывода вместо NULL подставляют значение по умолчанию функцией coalesce: она возвращает первый аргумент, который не NULL.

SQL
SELECT name, coalesce(email, '(no email)') AS email
FROM clients
ORDER BY id;

Aigerim Seitova

email
aigerim@example.com

Daniyar Akhmetov

email
(no email)

Madina Omarova

email
madina@example.com
Сокращено: первые 3 строки из 8.

ORDER BY, LIMIT, OFFSET и порядок выполнения запроса

Без ORDER BY база возвращает строки в том порядке, в каком ей быстрее, и он может меняться от запуска к запуску. ORDER BY сортирует по одному или нескольким выражениям: по возрастанию (ASC, по умолчанию) или по убыванию (DESC). Второй ключ сортировки работает внутри одинаковых значений первого.

SQL
SELECT name, category, price
FROM products
ORDER BY category, price DESC;

Espresso Blend 1 kg

category
coffee
price
12900.00

Ethiopia Yirgacheffe 250 g

category
coffee
price
5600.00

Colombia Supremo 250 g

category
coffee
price
4900.00

Hand Grinder

category
equipment
price
18500.00

French Press 600 ml

category
equipment
price
8900.00
Категории по алфавиту, внутри категории — от дорогого к дешёвому. Сокращено: первые 5 строк из 9.

При сортировке NULL считается больше любого значения: по возрастанию он оказывается в конце, по убыванию — в начале. Поменять это можно явно, NULLS FIRST или NULLS LAST:

SQL
SELECT name, city FROM clients ORDER BY city, id;
SELECT name, city FROM clients ORDER BY city DESC, id;
SELECT name, city FROM clients ORDER BY city DESC NULLS LAST, id;
Три сортировки по городу; id — второй ключ, чтобы порядок одинаковых городов был стабильным.

Aliya Bekova

city
NULL

Timur Kim

city
Shymkent

Zarina Kaliyeva

city
Karaganda

Daniyar Akhmetov

city
Astana

Sergey Pak

city
Astana

Aigerim Seitova

city
Almaty

Madina Omarova

city
Almaty

Ruslan Ivanov

city
Almaty
ORDER BY city DESC, id: клиентка без города первая.

Timur Kim

city
Shymkent

Zarina Kaliyeva

city
Karaganda

Daniyar Akhmetov

city
Astana

Sergey Pak

city
Astana

Aigerim Seitova

city
Almaty

Madina Omarova

city
Almaty

Ruslan Ivanov

city
Almaty

Aliya Bekova

city
NULL
ORDER BY city DESC NULLS LAST, id: теперь она последняя.

LIMIT ограничивает число строк, OFFSET пропускает строки перед ними. Так строят постраничный вывод. Документация настаивает: с LIMIT нужен ORDER BY, задающий однозначный порядок, иначе вы получите непредсказуемое подмножество. Поэтому в примере вторым ключом стоит id — на случай двух товаров с одинаковой ценой.

SQL
SELECT name, price
FROM products
ORDER BY price DESC, id
LIMIT 3;

Hand Grinder

price
18500.00

Gift Box

price
15000.00

Espresso Blend 1 kg

price
12900.00
Три самых дорогих товара.
SQL
SELECT name, price
FROM products
ORDER BY price DESC, id
LIMIT 3 OFFSET 3;

French Press 600 ml

price
8900.00

Ethiopia Yirgacheffe 250 g

price
5600.00

Colombia Supremo 250 g

price
4900.00
Следующая «страница»: строки с 4-й по 6-ю.

Почему псевдоним из SELECT нельзя использовать в WHERE? Потому что части запроса выполняются не в том порядке, в каком написаны. По описанию команды SELECT в документации сначала вычисляется FROM, затем WHERE отбрасывает строки, потом вычисляется список выбора, затем ORDER BY сортирует результат, и в конце LIMIT/OFFSET отрезают нужную часть.

FROMWHERESELECTORDER BYLIMIT
Логический порядок выполнения запроса из этого урока. GROUP BY и HAVING встают между WHERE и SELECT — о них в следующем уроке.
SQL
SELECT name, round(price * 0.9) AS sale_price
FROM products
WHERE sale_price < 5000;

-- ERROR:  column "sale_price" does not exist
-- LINE 3: WHERE sale_price < 5000;
--               ^
На шаге WHERE столбца sale_price ещё не существует.
SQL
SELECT name, round(price * 0.9) AS sale_price
FROM products
WHERE round(price * 0.9) < 5000
ORDER BY sale_price;
В WHERE повторяем выражение, а в ORDER BY псевдоним доступен: сортировка идёт после SELECT.

Ceramic Mug 350 ml

sale_price
2250

Green Sencha 100 g

sale_price
2880

Masala Chai 200 g

sale_price
3420

Colombia Supremo 250 g

sale_price
4410
Товары, которые со скидкой 10% стоят меньше 5000 ₸.

Упражнения с ответами

Все упражнения выполняются на учебной базе из первого раздела. Если вы меняли данные, загрузите shop.sql заново. Ответы проверены на PostgreSQL 17.11; ожидаемый вывод — в комментариях к решению.

Следующий шаг — соединить таблицы: вывести заказы вместе с именами клиентов, посчитать выручку по категориям и найти клиентов без заказов. Это тема урока «SQL: JOIN, GROUP BY и агрегаты» на той же учебной базе.

Как проверено4 · пройденосверено 11 октября 2026 г.
  • запущено, работает

    shop.sql (seed учебной базы)

    docker run -d --rm --name kb-pg-db0103 -e POSTGRES_PASSWORD=test postgres:17-alpine (PostgreSQL 17.11); загрузка через Git Bash `docker exec -i … psql -U postgres < shop.sql` и через PowerShell 7.6 `Get-Content shop.sql | docker exec -i …`; повторный запуск пересоздаёт таблицы; вывод загрузки в статье — реальный (load_first.txt)

  • запущено, работает

    Команды запуска (docker run / docker exec)

    последовательность выполнена в отдельном контейнере kb-pg-db0103-setup (имя заменено с shop-db): немедленный docker exec после docker run дал ошибку подключения (вставлена в статью дословно), через ~6 с загрузка прошла; \dt и запрос с -P null=NULL через stdin. Интерактивный режим `-it` с TTY не запускался (нет терминала у агента), команда отличается только флагом -t

  • запущено, работает

    Запросы урока (24 шт.: SELECT, WHERE, LIKE/ILIKE, NULL, ORDER BY, LIMIT/OFFSET, ошибка псевдонима в WHERE)

    каждый запрос — отдельный .sql, выполнен `docker exec -i kb-pg-db0103 psql -U postgres -X -P null=NULL < file`; таблицы и комментарии с выводом собраны в статью скриптом из файлов вывода; сокращённые таблицы помечены в подписи

  • запущено, работает

    Решения 10 упражнений (+ альтернативное решение упр. 9)

    выполнены на свежезагруженной базе, ожидаемый вывод в решениях — реальный; альтернатива `city <> 'Astana' OR city IS NULL` дала те же 6 строк

«Запущено» — код выполнен во временном проекте или контейнере, вывод в статье взят из прогона. «Частично» — проверено с заглушками вместо внешних сервисов. «Не запускалось» — нужны устройство, аккаунт или ключ; шаги сверены с официальной документацией. Файлы проверочного проекта и логи запусков сохранены в архиве InterLAB.

Расскажите о задаче — мы изучим запрос и свяжемся с вами

Есть задача?
Обсудим и оценим — бесплатно.

Расскажите о продукте или проблеме. Предложим архитектуру, срок и стоимость первой версии после изучения задачи.

  • Оценка объёма и рисков до старта
  • NDA — по вашему или нашему шаблону
  • Старт работ в течение недели

Не присылайте через форму пароли, ключи доступа и исходный код — безопасную передачу доступа обсудим отдельно.

Нажимая кнопку, вы соглашаетесь с обработкой персональных данных.