#mysql #sql
#mysql #sql
Вопрос:
Я думаю, это скорее вопрос шаблона проектирования, чем SQL.
В моем приложении пользователь может присоединиться, может создать магазин и загружать товары в свой магазин (допустим, есть пользователь, магазин (один к одному) и товары (многие к одному с магазинами).
Итак, я хочу иметь возможность выполнять определенные действия на основе времени и критериев (но только один раз), например, если через неделю после присоединения у пользователя нет магазина, я хочу отправить электронное письмо, или через 2 недели после присоединения к магазину, но товары не отправляются по электронной почте и т.д. — Но я хочу сделать это только один раз.
Это единственный запущенный один раз, который заставляет меня задуматься — так, например, допустим, у меня был этот запрос
select * from user where joineddt < '1 week ago date'
И у меня был скрипт, который запускался каждые 3 часа, запускал SQL, а затем выполнял любое событие (например, отправлял электронное письмо) Затем я хочу убедиться, что если этот скрипт был запущен снова, он не заберет никаких пользователей, которые уже были обработаны. Я думал о введении таблицы «события», в которой после запуска события для пользователя регистрируется запись для этого события, но это снова, похоже, не работает. Например, скажем, у меня была таблица событий, был идентификатор, пользователь, событие
select * from user a
left join event b on b.user = a.id
where a.joineddt < '1 week ago date'
and b.event = 'userjoined'
and b.id is null
Поэтому, когда в событиях нет записи, подходящей для события ‘userjoined’, оно не вернет результатов…Но на самом деле я хочу, чтобы он возвращал пользователей, у которых в таблице событий нет события для этого события ‘userjoined’?
Итак, кто-нибудь может придумать способ сделать то, что я предлагаю?
Ответ №1:
Ваш запрос всегда будет возвращать 0 строк, потому что если b.id равно нулю, b.событие никогда не может быть «подключено пользователем». Переместите критерии ‘userjoined’ в предложение join.
SELECT a.*
FROM user a
LEFT JOIN event b ON (b.user = a.id AND b.event = 'userjoined')
WHERE a.joineddt < '1 week ago date'
AND b.id IS NULL
Ответ №2:
Вам не нужно иметь дополнительную таблицу (объединения стоят дорого) для реализации вашего решения. В вашей пользовательской таблице просто добавьте два столбца даты с возможностью обнуления: ‘date_joined’ и ‘reminded’. Убедитесь, что в логике вашего приложения (которую вы можете определить на стороне таблицы / базы данных) значение ‘date_joined’ по умолчанию соответствует дате присоединения, а значение ‘reminded’ равно НУЛЮ.
Чтобы забрать пользователей, нуждающихся в напоминании:
SELECT * FROM users
WHERE date_joined > '1 week ago' AND reminded IS NULL
Обязательно заполните поле «напомнено» с указанием даты после отправки электронного письма. Таким образом, следующий запуск скрипта не обнаружит это.
Комментарии:
1. Эти 2 события были просто примером, событий много, и я хотел бы добавить больше с течением времени, не хотел бы добавлять столбцы для каждого типа события. С точки зрения затрат, это будет периодически запускаемый автономный демон, поэтому это не должно повлиять.