Авторский канал про Базы Данных и SQL
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!
Cотрудничество: @energy_c
РКН: https://clck.ru/3QREBc
Post #1426
2.22K

- 😁 31
- 👍 6
- 🔥 3
- ❤ 1
SQ @sql_ready
Showing posts older than #1428 · Back to latest


UNNEST() не сохраняет позицию элемента, что критично, когда важен порядок: восстановление списков, сортировка, работа с JSON-массивами.WITH ORDINALITY. Оно добавляет индекс элемента прямо при распаковке.SELECT recipe_id, ingredient, ord
FROM recipes,
UNNEST(ingredients) WITH ORDINALITY AS t(ingredient, ord);
UNNEST(), здесь мы сразу получаем порядковый номер — без оконных функций и без дополнительных JOIN.SELECT recipe_id,
STRING_AGG(ingredient, ', ' ORDER BY ord) AS ordered_list
FROM (
SELECT recipe_id, ingredient, ord
FROM recipes,
UNNEST(ingredients) WITH ORDINALITY t(ingredient, ord)
) q
GROUP BY recipe_id;
SELECT order_id,
item ->> 'name' AS name,
item ->> 'price' AS price,
ord
FROM orders,
jsonb_array_elements(items) WITH ORDINALITY AS t(item, ord);
WITH ORDINALITY в PostgreSQL, когда критична позиция элемента в массиве или JSON-списке.





В этой шпаргалке собраны функции MySQL, применяемые для получения отдельных компонентов даты и времени: года, месяца, дня, часов, минут, секунд, номера недели и дня недели. Эти операции используются в большинстве рабочих запросов — от фильтрации и группировки данных до подготовки отчётов и временной аналитики.
SELECT *
FROM generate_series('2025-01-01', '2025-01-31', interval '1 day');
generate_series() создаёт виртуальную таблицу с шагом по дате.SELECT g.day, COUNT(o.id) AS total
FROM generate_series('2025-01-01', '2025-01-31', interval '1 day') AS g(day)
LEFT JOIN orders o ON date(o.created_at) = g.day
GROUP BY g.day
ORDER BY g.day;






• Проверим, существует ли прямой путь, простой случай, но часто самый важный;
• Расширим поиск и найдём маршруты вида A => X => B, где X — автоматически вычисленная пересадка;
• Построим цепочки A => X => Y => B, что по сути является маленьким обходом графа.
WHERE, запросы тормозят. В PostgreSQL это решается GENERATED ALWAYS AS … STORED — выражение вычисляется один раз и хранится как обычное поле.CREATE TABLE events (
id BIGSERIAL PRIMARY KEY,
payload JSONB NOT NULL,
event_type TEXT GENERATED ALWAYS AS (payload->>'type') STORED
);
event_type больше не вычисляется на лету — значение лежит прямо в строке.SELECT id
FROM events
WHERE event_type = 'purchase';
CREATE INDEX idx_events_event_type
ON events(event_type);
EXPLAIN ANALYZE
SELECT id
FROM events
WHERE event_type = 'purchase';
Index Scan, без тяжёлых операций над JSONB. Сгенерированные колонки отлично подходят для повторяющихся вычислений:




SKIP LOCKED позволяет управлять конкурентным доступом на уровне строки, а не всей таблицы, поэтому воркеры не ждут друг друга и не создают лишних блокировок.• Забираем задачи параллельно и без конфликтов;
• Делаем атомарный “взять + обновить” в одном запросе;
• Распределяем очереди между воркерами под высокой нагрузкой.