Вы когда-нибудь тратили полдня на написание сложного запроса, который потом оказывался медленным, как улитка? Или часами проектировали схему базы данных, чтобы через месяц понять, что она не масштабируется? Знакомо? Тогда эта подборка для вас. Я собрал 10 промтов для работы с SQL и PostgreSQL, которые покрывают самые частые боли аналитиков и разработчиков: от генерации сложных JOIN и оконных функций до диагностики медленных запросов и автоматизации рутины. Каждый промт — это готовый шаблон, который можно адаптировать под свою задачу, с примером использования и пояснением, какую именно проблему он решает. Поехали!
1. Генерация сложного JOIN-запроса с несколькими условиями
Задача: Написать SQL-запрос, который объединяет несколько таблиц с использованием LEFT JOIN, INNER JOIN и дополнительными условиями в ON, чтобы получить данные из нескольких связанных сущностей.
Промт:
Напиши PostgreSQL запрос, который выбирает из таблиц
orders,customersиorder_itemsследующие поля:order_id,customer_name,order_date,product_name,quantity,price. ИспользуйINNER JOINдляcustomersиorder_items, а дляproducts—LEFT JOIN, так как не все товары могут быть в каталоге. Добавь условие, чтобы отфильтровать заказы за последние 30 дней. Отсортируй по дате заказа по убыванию.
Пример результата:
SELECT
o.order_id,
c.customer_name,
o.order_date,
p.product_name,
oi.quantity,
oi.price
FROM orders o
INNER JOIN customers c ON o.customer_id = c.customer_id
INNER JOIN order_items oi ON o.order_id = oi.order_id
LEFT JOIN products p ON oi.product_id = p.product_id
WHERE o.order_date >= CURRENT_DATE - INTERVAL '30 days'
ORDER BY o.order_date DESC;
Как это помогает: Такой промт экономит время на вспоминание синтаксиса JOIN и позволяет быстро получить основу запроса, которую можно доработать под конкретные нужды.
2. Оптимизация медленного запроса с помощью EXPLAIN ANALYZE
Задача: Понять, почему запрос выполняется слишком долго, и найти узкие места.
Промт:
У меня есть PostgreSQL запрос, который выполняется 15 секунд. Вот его код: [вставьте запрос]. Используй
EXPLAIN ANALYZEдля этого запроса и объясни, какие операции занимают больше всего времени. Предложи конкретные шаги по оптимизации: например, добавление индексов, изменение условий JOIN или переписывание запроса.
Пример результата:
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders WHERE customer_id = 123 AND order_date > '2026-01-01';
Вывод: План показывает Seq Scan по таблице orders, что говорит о необходимости индекса на (customer_id, order_date). После добавления индекса время выполнения сократилось до 50 мс.
Как это помогает: Промт не только выполняет EXPLAIN, но и интерпретирует результат, что особенно полезно для новичков, которые не знают, как читать план выполнения.
3. Написание оконных функций для аналитики (ROW_NUMBER, LAG, LEAD)
Задача: Вычислить скользящее среднее, ранжировать записи или получить предыдущее/следующее значение в группе.
Промт:
Напиши SQL-запрос для PostgreSQL, который для каждого клиента выводит его заказы с полем
order_rank(ранг заказа по дате для каждого клиента) и полемprev_order_date(дата предыдущего заказа). Используй оконные функцииROW_NUMBER()иLAG(). Также добавь скользящее среднее суммы заказа за последние 3 заказа (окно по дате).
Пример результата:
SELECT
customer_id,
order_date,
amount,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date) AS order_rank,
LAG(order_date) OVER (PARTITION BY customer_id ORDER BY order_date) AS prev_order_date,
AVG(amount) OVER (PARTITION BY customer_id ORDER BY order_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg_3
FROM orders;
Как это помогает: Оконные функции — одна из самых мощных и сложных тем в SQL. Такой промт даёт готовый шаблон, который легко адаптировать под свои метрики.
4. Проектирование схемы базы данных для нового проекта
Задача: Спроектировать нормализованную схему БД для интернет-магазина с учётом требований к масштабируемости.
Промт:
Спроектируй схему базы данных для интернет-магазина на PostgreSQL. Основные сущности: пользователи, товары, категории, заказы, элементы заказа. Учти, что товары могут иметь несколько категорий, а заказ может содержать несколько товаров. Добавь необходимые индексы для ускорения запросов: по email пользователя, по дате заказа, по внешним ключам. Выдай SQL-скрипт для создания таблиц с ограничениями (PRIMARY KEY, FOREIGN KEY, NOT NULL).
Пример результата:
CREATE TABLE users (
user_id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE categories (
category_id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
CREATE TABLE products (
product_id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
price NUMERIC(10,2) NOT NULL
);
CREATE TABLE product_categories (
product_id INT REFERENCES products(product_id),
category_id INT REFERENCES categories(category_id),
PRIMARY KEY (product_id, category_id)
);
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
user_id INT REFERENCES users(user_id),
order_date TIMESTAMP DEFAULT NOW(),
total NUMERIC(10,2)
);
CREATE TABLE order_items (
order_id INT REFERENCES orders(order_id),
product_id INT REFERENCES products(product_id),
quantity INT NOT NULL,
price NUMERIC(10,2) NOT NULL,
PRIMARY KEY (order_id, product_id)
);
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_order_date ON orders(order_date);
CREATE INDEX idx_order_items_product_id ON order_items(product_id);
Как это помогает: Этот промт экономит часы на проектировании и гарантирует, что схема будет нормализованной и с правильными индексами с самого начала.
5. Автоматизация рутинных задач: генерация отчётов по расписанию
Задача: Создать SQL-запрос, который формирует ежедневный отчёт по продажам и может быть использован в cron или встроен в BI-инструмент.
Промт:
Напиши SQL-запрос для PostgreSQL, который выдаёт ежедневный отчёт по продажам за вчера: количество заказов, общая выручка, средний чек, количество уникальных клиентов. Сгруппируй данные по дням. Добавь фильтр по
order_dateза вчерашний день, используяCURRENT_DATE - 1. Выведи результат в удобном для чтения виде.
Пример результата:
SELECT
DATE(order_date) AS day,
COUNT(*) AS total_orders,
SUM(total) AS revenue,
AVG(total) AS avg_check,
COUNT(DISTINCT user_id) AS unique_customers
FROM orders
WHERE order_date >= CURRENT_DATE - 1 AND order_date < CURRENT_DATE
GROUP BY day
ORDER BY day;
Как это помогает: Промт даёт готовый шаблон для регулярной отчётности, который можно автоматизировать через cron или встроить в дашборд.
6. Поиск и исправление дубликатов в данных
Задача: Найти дублирующиеся записи в таблице и удалить их, сохранив одну (например, с минимальным ID).
Промт:
В таблице
usersесть дубликаты по полюuser_id. Используй оконную функциюROW_NUMBER().
Пример результата:
-- Найти дубликаты
SELECT email, COUNT(*) AS cnt
FROM users
GROUP BY email
HAVING COUNT(*) > 1;
-- Удалить дубликаты, оставив минимальный id
WITH ranked AS (
SELECT
user_id,
ROW_NUMBER() OVER (PARTITION BY email ORDER BY user_id) AS rn
FROM users
)
DELETE FROM users
WHERE user_id IN (SELECT user_id FROM ranked WHERE rn > 1);
Как это помогает: Очистка данных — одна из самых частых задач аналитика. Промт даёт безопасный и эффективный способ удалить дубликаты без потери нужных данных.
7. Трансформация данных: из строк в столбцы (PIVOT) и обратно
Задача: Преобразовать данные из вертикального формата в горизонтальный (кросс-таблица) и наоборот.
Промт:
У меня есть таблица
salesс полями:month,product,amount. Напиши запрос, который преобразует данные в кросс-таблицу, где строки — месяцы, столбцы — продукты, а значения — сумма продаж. Используй условную агрегацию сCASE. Также напиши обратное преобразование (UNPIVOT) для таблицы, где данные уже в горизонтальном виде.
Пример результата:
-- PIVOT
SELECT
month,
SUM(CASE WHEN product = 'A' THEN amount ELSE 0 END) AS product_a,
SUM(CASE WHEN product = 'B' THEN amount ELSE 0 END) AS product_b,
SUM(CASE WHEN product = 'C' THEN amount ELSE 0 END) AS product_c
FROM sales
GROUP BY month
ORDER BY month;
-- UNPIVOT (для таблицы monthly_sales)
SELECT month, 'A' AS product, product_a AS amount FROM monthly_sales
UNION ALL
SELECT month, 'B', product_b FROM monthly_sales
UNION ALL
SELECT month, 'C', product_c FROM monthly_sales;
Как это помогает: Часто данные нужно переформатировать для отчётов или визуализации. Промт показывает, как это сделать без использования расширений, только стандартным SQL.
8. Работа с JSON и JSONB в PostgreSQL
Задача: Извлечь данные из JSON-поля, отфильтровать по ключу и агрегировать.
Промт:
В таблице
eventsесть полеmetadataтипа JSONB, которое содержит различные атрибуты события. Напиши запрос, который извлекает значение ключаuser_agent, фильтрует события, гдеmetadata->>'status' = 'success', и группирует поuser_agent, считая количество событий. Используй операторы->>и@>для фильтрации.
Пример результата:
SELECT
metadata->>'user_agent' AS user_agent,
COUNT(*) AS event_count
FROM events
WHERE metadata @> '{"status": "success"}'
GROUP BY user_agent
ORDER BY event_count DESC;
Как это помогает: PostgreSQL — одна из лучших БД для работы с JSON. Промт показывает, как эффективно извлекать и агрегировать данные из JSONB, что часто требуется в современных приложениях.
9. Оптимизация с помощью индексов: какие и когда создавать
Задача: Определить, какие индексы нужно создать для ускорения конкретных запросов.
Промт:
У меня есть таблица
ordersс полямиcustomer_id,order_date,status. Есть частые запросы: 1) поиск заказов по клиенту и дате; 2) фильтрация по статусу. Проанализируй, какие индексы нужны, и напиши SQL для их создания. Объясни, почему выбранные индексы эффективны, и упомяни композитные индексы.
Пример результата:
CREATE INDEX idx_orders_customer_date ON orders(customer_id, order_date);
CREATE INDEX idx_orders_status ON orders(status);
Объяснение: Для запроса с фильтром по customer_id и order_date лучше всего подходит композитный индекс, так как он позволяет быстро отсечь ненужные строки. Для фильтра по status достаточно одиночного индекса, но если статусов мало (например, 'new', 'paid', 'shipped'), то индекс может быть неэффективен, и лучше использовать частичный индекс.
Как это помогает: Правильные индексы — ключ к производительности. Промт даёт не только код, но и понимание, когда и какие индексы создавать.
10. Анализ логов и текстовых данных с помощью полнотекстового поиска
Задача: Найти записи в таблице, содержащие определённые слова или фразы, с учётом ранжирования по релевантности.
Промт:
В таблице
articlesесть полеbodyс текстом. Напиши запрос с использованием полнотекстового поиска PostgreSQL, который находит все статьи, содержащие слова 'database' и 'indexing', и сортирует их по релевантности. Используйto_tsvectorиto_tsquery. Также добавь подсветку совпадений с помощьюts_headline.
Пример результата:
SELECT
title,
ts_headline(body, query) AS highlighted_body,
ts_rank(to_tsvector(body), query) AS rank
FROM articles, to_tsquery('english', 'database & indexing') AS query
WHERE to_tsvector(body) @@ query
ORDER BY rank DESC;
Как это помогает: Полнотекстовый поиск в PostgreSQL — мощный инструмент, который часто недооценивают. Промт показывает, как использовать его для поиска и ранжирования, что экономит время на написании сложных LIKE-запросов.
Заключение
Эти 10 промтов — лишь вершина айсберга. Но они покрывают 80% типовых задач, с которыми сталкивается аналитик или разработчик при работе с PostgreSQL. Главное — не просто копировать их, а понимать, как они работают, и адаптировать под свои данные. Начните с одного-двух промтов, попробуйте их на своих данных, и вы увидите, как много времени они экономят. А если хотите углубиться в тему, обратите внимание на официальную документацию PostgreSQL — там есть множество примеров и рекомендаций. Удачи в запросах!
Комментарии