Ситуация
Моя цель - иметь годовой cronjob, который удаляет определенные данные из базы данных в зависимости от возраста. В моем распоряжении у меня есть полномочия Bash и MySQL. Я начал писать Bash script, но потом мне показалось, что, возможно, я мог бы сделать все с помощью всего одного SQL-запроса.
Я больше программист по своей природе, и у меня не было большого опыта работы с структурами данных, поэтому я хотел бы помочь.
Таблицы/структура данных
Соответствующие таблицы и столбцы для этого запроса выглядят следующим образом:
Регистрация:
+-----+-------------------+
| Id | Registration_date |
+-----+-------------------+
| 2 | 2011-10-03 |
| 3 | 2011-10-06 |
| 4 | 2011-10-07 |
| 5 | 2011-10-07 |
| 6 | 2011-10-10 |
| 7 | 2011-10-13 |
| 8 | 2011-10-14 |
| 9 | 2011-10-14 |
| 10 | 2011-10-17 |
+-------------------------+
AssociatedClient:
+-----------+-----------------+
| Client_id | Registration_id |
+-----------+-----------------+
| 2 | 2 |
| 3 | 2 |
| 3 | 4 |
| 4 | 5 |
| 3 | 6 |
| 5 | 6 |
| 3 | 8 |
| 8 | 9 |
| 7 | 10 |
+-----------------------------+
Клиент: здесь используется только идентификатор.
Как вы можете видеть, это простое отношение "многие ко многим". Клиент может иметь несколько имен для своего имени, а регистрация может иметь несколько клиентов.
Цель
Мне нужно удалить все регистрационные данные и данные клиента для клиентов, у которых не было новой регистрации через 5 лет. Звучит просто, правильно?
Сложная часть
Данные должны храниться, если любой другой клиент на любой регистрации от конкретного клиента имеет новую регистрацию в течение 5 лет.
Итак, представьте клиента A, имеющего 4 регистрации только с ним в них, и 1 регистрацию с собой и с клиентом B. Все 5 регистраций старше 5 лет. Если у клиента B не было новой регистрации через 5 лет, все должно быть удалено: регистрация клиентов и регистрация клиентов. Если B сделал новую регистрацию в течение 5 лет, все клиентские данные должны храниться, включая его собственные старые регистрации.
Что я пробовал
Построение моего запроса, я догадался об этом:
DELETE * FROM `Registration` AS Reg
WHERE TIMESTAMPDIFF(YEAR, Reg.`Registration_date`, NOW()) >= 5
AND
(COUNT(`Id`) FROM `Registration` AS Reg2
WHERE Reg2.`Id` IN (SELECT `Registration_id` FROM `AssociatedClient` AS Clients
WHERE Clients.`Client_id` IN (SELECT `Client_id` FROM `AssociatedClient` AS Clients2
WHERE Clients2.`Registration_id` IN -- stuck
#I need all the registrations from the clients associated with the first
# (outer) registration here, that are newer than 5 years.
) = 0 -- No newer registrations from any associated clients
Пожалуйста, поймите, что у меня очень ограниченный опыт работы с SQL. Я понимаю, что даже то, что я получил до сих пор, может быть сильно оптимизировано (с объединениями и т.д.) И может даже не быть правильным.
Причина, по которой я застрял, заключается в том, что решение, которое я имел в виду, будет работать, если бы я мог использовать какой-то цикл, и я только понял, что это не то, что вы легко делаете в SQL-запросе такого рода.
Любая помощь
Очень ценится.