Как составить SQL-запрос для поиска пользователей без заказов за последние 3 месяца?
Поиск пользователей без заказов за определённый период — типичная задача при анализе активности клиентов и работе с базами данных. Для решения этой задачи необходимо использовать SQL-запрос с операцией LEFT JOIN или NOT EXISTS, чтобы найти тех пользователей, у которых отсутствуют записи о заказах за последние три месяца.
Рассмотрим несколько вариантов решения. Предположим, у нас есть две таблицы: users (с полями user_id, name, email) и orders (с полями order_id, user_id, order_date).
Первый вариант с использованием LEFT JOIN:
SELECT u.user_id, u.name, u.email
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id
AND o.order_date >= DATE_SUB(CURDATE(), INTERVAL 3 MONTH)
WHERE o.order_id IS NULL;
В этом запросе мы соединяем таблицу пользователей с таблицей заказов, но только с теми заказами, которые были сделаны за последние 3 месяца. Условие WHERE o.order_id IS NULL отфильтрует только тех пользователей, для которых не нашлось соответствующих заказов.
Второй вариант с использованием NOT EXISTS:
SELECT u.user_id, u.name, u.email
FROM users u
WHERE NOT EXISTS (
SELECT 1
FROM orders o
WHERE o.user_id = u.user_id
AND o.order_date >= DATE_SUB(CURDATE(), INTERVAL 3 MONTH)
);
Этот подход проверяет для каждого пользователя наличие хотя бы одного заказа за последние 3 месяца. Если такого заказа нет, пользователь попадает в результат.
Третий вариант с использованием NOT IN:
SELECT u.user_id, u.name, u.email
FROM users u
WHERE u.user_id NOT IN (
SELECT DISTINCT o.user_id
FROM orders o
WHERE o.order_date >= DATE_SUB(CURDATE(), INTERVAL 3 MONTH)
);
Важные моменты: функция DATE_SUB(CURDATE(), INTERVAL 3 MONTH) вычисляет дату три месяца назад от текущей даты. В PostgreSQL используйте CURRENT_DATE — INTERVAL ‘3 months’, в SQL Server — DATEADD(MONTH, -3, GETDATE()).
Для оптимизации производительности рекомендуется создать индекс на поле order_date в таблице orders и на user_id в обеих таблицах. Вариант с LEFT JOIN обычно работает быстрее на больших объёмах данных, но NOT EXISTS может быть эффективнее при правильной индексации.
Выбор конкретного варианта зависит от структуры вашей базы данных, объёма данных и используемой СУБД.