Аналитику нужно посчитать выручку по клиентам, а разработчику — разобраться в чужом запросе. Искусственный интеллект способен за секунды превратить описание задачи в SQL. Но код может выполняться без ошибок и при этом считать один заказ дважды или игнорировать возвраты.
SQL с помощью ИИ — это не только генерация кода: модель умеет объяснять запросы, предлагать тесты, искать проблемы с соединениями и разбирать планы выполнения. Для этого подходят чаты и ИИ для программирования. Качество результата зависит прежде всего от контекста и проверки, особенно когда на кону анализ данных.
Как написать SQL-запрос с помощью ИИ: пошаговая инструкция
Задача — получить выручку по клиентам за сентябрь 2026 года. В учебном примере это сумма quantity × unit_price по оплаченным заказам. Считаем, что unit_price указана в рублях без налогов и скидок; доставка и возвраты в схеме не отражены. В реальном магазине определение метрики нужно согласовать с бизнесом.
Шаг 1. Сформулируйте задачу для нейросети
Плохой запрос к ИИ: «Покажи продажи за месяц». Неясно, что считать продажей, как группировать данные и какие статусы исключать. Модель заполнит пробелы догадками. Поэтому контекст задачи важнее красивой формулировки.
Полезное текстовое описание задачи выглядит так:
Для PostgreSQL рассчитай выручку по каждому клиенту за период с 1 сентября 2026 года включительно до 1 октября 2026 года не включительно. Учитывай только заказы со статусом
paid. Суммируйquantity × unit_priceпо позициям заказов. Верни ID и имя клиента, число уникальных оплаченных заказов и выручку. Показывай только клиентов с такими заказами. Сортируй по выручке по убыванию, затем по ID клиента.
Шаг 2. Передайте ИИ структуру базы данных
Модели необходимы структура таблиц, названия столбцов, типы данных, первичный ключ и внешний ключ, а также связи между таблицами и их кратность. Без схемы она может выдумать orders.total_amount или соединить неподходящие поля.
Используем такую учебную схему БД:
CREATE TABLE customers (
id BIGINT PRIMARY KEY,
full_name TEXT NOT NULL
);
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
customer_id BIGINT NOT NULL REFERENCES customers(id),
created_at TIMESTAMPTZ NOT NULL,
status TEXT NOT NULL
);
CREATE TABLE order_items (
id BIGINT PRIMARY KEY,
order_id BIGINT NOT NULL REFERENCES orders(id),
quantity INTEGER NOT NULL CHECK (quantity > 0),
unit_price NUMERIC(12, 2) NOT NULL CHECK (unit_price >= 0)
);
В customers одна строка — клиент, в orders — заказ, в order_items — позиция. Связи: customers.id → orders.customer_id и orders.id → order_items.order_id. У заказа несколько позиций, поэтому после JOIN его ID может повториться.
Для большой базы передавайте лишь относящиеся к задаче таблицы, словарь статусов и правила расчёта. Метаданные можно извлечь из information_schema. Некоторые инструменты получают структуру через разрешённое подключение, в том числе по Model Context Protocol (MCP). Подключение не отменяет контроль доступа и проверку схемы.
Шаг 3. Сгенерируйте SQL-запрос
Готовый промпт для генерации SQL-запроса с задачей и схемой — основа воспроизводимого результата. Генерация SQL-запросов без этих вводных превращается в угадывание:
PostgreSQL. Таблицы:
customers(id, full_name),orders(id, customer_id, created_at TIMESTAMPTZ, status),order_items(id, order_id, quantity, unit_price). Связи:orders.customer_id → customers.id,order_items.order_id → orders.id; несколько позиций на заказ. Заказы со статусомpaidза сентябрь 2026 по UTC: с 01.09 включительно до 01.10 исключительно. Выручка —SUM(quantity * unit_price)в рублях. Нужныcustomer_id,full_name, число уникальных заказовpaid_orders,revenue: одна строка на клиента с покупками. Сортировка: выручка по убыванию, затем ID по возрастанию. Не придумывай полей. Верни SQL и поясни, как исключил задвоение заказов.
Корректный запрос для нашей схемы:
SELECT
c.id AS customer_id,
c.full_name,
COUNT(DISTINCT o.id) AS paid_orders,
SUM(oi.quantity * oi.unit_price) AS revenue
FROM customers AS c
JOIN orders AS o
ON o.customer_id = c.id
JOIN order_items AS oi
ON oi.order_id = o.id
WHERE o.status = 'paid'
AND o.created_at >= TIMESTAMPTZ '2026-09-01 00:00:00+00'
AND o.created_at < TIMESTAMPTZ '2026-10-01 00:00:00+00'
GROUP BY c.id, c.full_name
ORDER BY revenue DESC, customer_id;
SELECT задаёт результат, JOIN соединяет три таблицы, WHERE фильтрует статус и даты, GROUP BY собирает строки по клиентам, SUM рассчитывает выручку, ORDER BY сортирует. COUNT(DISTINCT o.id) обязателен: после JOIN один заказ встречается столько раз, сколько в нём позиций.
Как объяснить готовый SQL-запрос с помощью ИИ
Чтобы объяснить SQL-запрос, дайте модели код, схему и ожидаемую метрику. Иначе она прокомментирует синтаксис, но может ошибиться в бизнес-смысле.
Объясни этот SQL для PostgreSQL: [код и схема]. Какие строки остаются после JOIN и WHERE? На каком уровне происходит GROUP BY? Зачем COUNT использует DISTINCT? Почему верхняя граница периода исключена? Укажи три причины возможной неверной выручки и перескажи логику словами для заказчика отчёта.
FROMиJOINсоздают строки «клиент — заказ — позиция», поэтому заказ с двумя позициями представлен дважды.WHEREоставляет только оплаченные сентябрьские заказы по UTC.GROUP BYсобирает позиции по клиентам;COUNT(DISTINCT)считает заказы,SUM— стоимость товаров.SELECTвыводит колонки,ORDER BYсортирует результат.
Это логическая модель работы запроса, а не фактическая последовательность чтения строк: оптимизатор PostgreSQL может менять физический план. Его анализируют отдельно через EXPLAIN.
Как проверить SQL-запрос, сгенерированный нейросетью
Проверяйте код на данных с заранее известным ответом. Это общий принцип ИИ в тестировании кода. SQL может выполняться без ошибок и возвращать неверную сумму. Ниже — тестовые данные для проверки результата.
INSERT INTO customers (id, full_name) VALUES
(1, 'Анна'), (2, 'Борис'), (3, 'Вера');
INSERT INTO orders (id, customer_id, created_at, status) VALUES
(101, 1, '2026-09-05 12:00:00+00', 'paid'),
(102, 1, '2026-09-29 10:00:00+00', 'canceled'),
(103, 2, '2026-09-30 23:30:00+00', 'paid'),
(104, 3, '2026-10-01 00:00:00+00', 'paid'),
(105, 1, '2026-09-19 09:00:00+00', 'paid'),
(106, 2, '2026-09-12 09:00:00+00', 'pending');
INSERT INTO order_items (id, order_id, quantity, unit_price) VALUES
(1001, 101, 2, 500.00),
(1002, 101, 1, 300.00),
(1003, 102, 1, 999.00),
(1004, 103, 3, 400.00),
(1005, 104, 1, 1000.00),
(1006, 105, 1, 250.00),
(1007, 105, 2, 75.00),
(1008, 106, 1, 600.00);
У Анны заказ 101: 2 × 500 + 300 = 1300, заказ 105: 250 + 2 × 75 = 400. Итого два заказа и 1700 рублей. У Бориса заказ 103 на 1200 рублей. Заказы 102 и 106 исключены по статусу, 104 — по дате.
| customer_id | full_name | paid_orders | revenue |
|---|---|---|---|
| 1 | Анна | 2 | 1700.00 |
| 2 | Борис | 1 | 1200.00 |
SELECT o.id, o.customer_id,
SUM(oi.quantity * oi.unit_price) AS order_revenue
FROM orders AS o
JOIN order_items AS oi ON oi.order_id = o.id
WHERE o.status = 'paid'
AND o.created_at >= TIMESTAMPTZ '2026-09-01 00:00:00+00'
AND o.created_at < TIMESTAMPTZ '2026-10-01 00:00:00+00'
GROUP BY o.id, o.customer_id
ORDER BY o.id;
Какие ошибки допускает ИИ при генерации SQL
Различайте синтаксические ошибки, при которых СУБД отвергает код, и логические ошибки, когда запрос работает, но показывает неверные цифры:
- Несуществующий столбец.
SUM(o.total_amount)не работает: цены хранятся вorder_items. - Неверный JOIN.
oi.id = o.idсравнивает разные сущности; нужноoi.order_id = o.id. - Дублирование строк.
COUNT(o.id)даст Анне четыре заказа вместо двух, хотя выручка останется 1700. - Ошибка GROUP BY. Лишний неагрегированный столбец может вызвать ошибку или неоднозначную группировку; перечень полей следует проверить.
- Неправильные даты.
created_at <= '2026-09-30'исключит события после полуночи 30 сентября; используйте полуоткрытый интервал. - Смешение SQL-диалектов.
DATE_SUB(..., INTERVAL 30 DAY)характерен для MySQL, тогда как PostgreSQL использует, например,CURRENT_TIMESTAMP - INTERVAL '30 days'.
Также проверьте NULL, часовые пояса, статусы оплат и возвраты.
Как исправить ошибку в SQL с помощью ИИ
Пример логической ошибки — четыре заказа у Анны вместо двух при COUNT(o.id) после JOIN. Чтобы исправить ошибку в SQL с помощью ИИ, передайте код и ожидаемый результат:
PostgreSQL. Для клиента 1 код показывает
paid_orders = 4, ожидается 2: заказ 101 и заказ 105, в каждом по две позиции. В запросе после JOIN используетсяCOUNT(o.id). Найди причину, предложи минимальное исправление, сохрани сумму выручки, дай проверочный SELECT. Схема: [схема]; запрос: [код].
SELECT
c.id AS customer_id,
c.full_name,
COUNT(DISTINCT o.id) AS paid_orders,
SUM(oi.quantity * oi.unit_price) AS revenue
FROM customers AS c
JOIN orders AS o ON o.customer_id = c.id
JOIN order_items AS oi ON oi.order_id = o.id
WHERE o.status = 'paid'
AND o.created_at >= TIMESTAMPTZ '2026-09-01 00:00:00+00'
AND o.created_at < TIMESTAMPTZ '2026-10-01 00:00:00+00'
GROUP BY c.id, c.full_name
ORDER BY revenue DESC, customer_id;
После исправления снова сравните все колонки с эталоном. DISTINCT не лечит любой неверный JOIN; например, SUM(DISTINCT price) удалит разные покупки с одинаковой ценой. Иногда дочерние таблицы лучше агрегировать заранее или проверять наличие строк через EXISTS.
Как оптимизировать SQL-запрос с помощью ИИ
Для медленного запроса ИИ нужны SQL-код, структура таблиц, объёмы, существующие индексы базы данных и план выполнения запроса. Без этого совет «добавь индекс» остаётся догадкой.
Пример: преобразование created_at в дату может помешать использованию обычного индекса и изменить границы суток при другой настройке часового пояса:
WHERE o.created_at::date BETWEEN DATE '2026-09-01'
AND DATE '2026-09-30'
WHERE o.created_at >= TIMESTAMPTZ '2026-09-01 00:00:00+00'
AND o.created_at < TIMESTAMPTZ '2026-10-01 00:00:00+00'
Возможные кандидаты — индексы orders(status, created_at) и order_items(order_id), если их ещё нет. Но индексы занимают место и удорожают запись, а небольшие таблицы PostgreSQL иногда быстрее читает последовательно. Никакого гарантированного ускорения без измерений нет.
EXPLAIN (ANALYZE, BUFFERS)
SELECT ...; -- подставьте проверенный SELECT
EXPLAIN ANALYZE показывает фактическое время и число обработанных строк, BUFFERS — работу со страницами данных. Важно: ANALYZE действительно выполняет запрос; с командами изменения данных соблюдайте особую осторожность. Подробнее — в документации PostgreSQL.
Вот запрос, схема, размеры таблиц, индексы и план EXPLAIN (ANALYZE, BUFFERS): [данные]. Найди самые затратные узлы, предложи до трёх изменений с компромиссами. Для каждого укажи, как сравнить скорость и результат до и после. Не меняй правила расчёта.
Готовые промпты для работы с SQL через нейросеть
Генерация SQL-запросов требует не только описания задачи, но и ограничений. Эти шаблоны можно использовать без передачи настоящих клиентских данных:
| Задача | Пример промпта |
|---|---|
| Создать запрос по описанию | «Для PostgreSQL составь SELECT: список клиентов, у которых за последние 90 дней было не менее трёх оплаченных заказов. Схема: [таблицы, поля, связи]. Одна строка — один клиент. Верни ID, имя и число заказов. Не используй поля вне схемы; поясни фильтр дат». |
| Объяснить сложный SQL | «Разбери этот запрос по шагам: [код]. Схема: [описание]. Покажи, что считается до и после агрегации, какие строки отбрасываются и где возможны NULL или дубликаты. Заверши объяснением для бизнес-заказчика в трёх предложениях». |
| Проверить соединения | «Проверь JOIN в коде [SQL]. Связи: [PK/FK и кратность]. Какое количество строк ожидается до и после каждого соединения? Укажи, где суммы могут умножаться, и предложи диагностические SELECT для проверки». |
| Найти ошибку | «PostgreSQL возвращает [текст ошибки / неверный результат]. Ожидалось [значение], получилось [значение]. Вот SQL, схема и тестовый набор: [данные]. Найди причину, исправь минимально, предложи регрессионный тест». |
| Ускорить запрос | «Предложи улучшения для [SQL] на PostgreSQL. Строк в таблицах: [объёмы], индексы: [список], план: [EXPLAIN]. Объясни компромиссы. Не утверждай, что ускорение есть, пока его не измерили». |
| Перевести в другой диалект | «Перепиши [SQL] с PostgreSQL на MySQL 8.4. Сохрани смысл фильтров дат, группировки и обработки NULL. Перечисли несовместимые функции и операции, покажи тестовые случаи для сравнения результатов». |
Ограничения и безопасность при работе с SQL через ИИ
Опасно давать агенту доступ к рабочей базе с правом записи и автоматически выполнять его SQL. UPDATE без нужного WHERE меняет множество строк, DELETE удаляет записи, DROP — объекты базы. Текстовая команда пользователя не заменяет разрешение на такие действия.
- Проверяйте код в тестовой среде с обезличенными данными: тяжёлый
SELECTтоже может перегрузить сервер. - Выдавайте минимальные права, по возможности только чтение; не позволяйте агенту автоматически выполнять изменения в production.
- Не передавайте в облачные чаты пароли, ключи доступа, конфиденциальные данные клиентов и коммерческие секреты.
- Для
UPDATE,DELETE,DROPпроверяйте условия, число затронутых строк, возможность отката и резервное копирование.
Если даже схему нельзя передавать вовне, рассмотрите локальные LLM или утверждённый корпоративный контур. Локальное размещение не отменяет проверки внешних интеграций и журналов.
Итог: SQL с помощью ИИ экономит время при написании и анализе кода, но контроль метрик остаётся за человеком. Если запросы хранятся рядом с приложением, работать с SQL-файлами можно в AI-IDE Kodik — без обещаний автоматического доступа к любой базе.




