Я пытаюсь применить рекурсивную логику.
У меня есть следующие данные в таблице tbl_appointment
( recur_type
: 1 = еженедельно, 2 = ежемесячно, 0 = не рекурсивно):
appointment_id user_id date recur_type ..... 18 56 2014-06-02 1 19 56 2014-06-15 2 20 56 2014-06-20 0 21 56 2014-07-20 2
У меня есть следующие критерии для извлечения данных: если я получаю данные за июль 2014 года (7-й месяц), тогда
appointment_id(21)
(1 строка) и … appointment_id(18)
еженедельно рекурсивно, выбираются повторы в июле (4 строки):
appointment_id user_id date recur_type ..... 18 56 2014-07-07 1 18 56 2014-07-14 1 18 56 2014-07-21 1 18 56 2014-07-28 1
Примечание. Дата изменяется, поскольку назначение является рекурсивным для каждой недели, что означает, что я добавляю 7 дней к каждой дате. 2014-06-02 + 7 дней = 2014-06-09 и так далее. Таким образом, для июля дата составляет 2014-07-07.
appointment_id(19)
ежемесячно рекурсивно, повторы в июле выбираются (1 строка):
appointment_id user_id date recur_type ..... 19 56 2014-07-15 2
Примечание. Дата изменяется, поскольку назначение является рекурсивным для каждого месяца, что означает, что я добавляю один месяц к дате.
Конечный результат (всего 6 строк):
appointment_id user_id date recur_type ..... 21 56 2014-07-20 2 18 56 2014-07-04 1 18 56 2014-07-11 1 18 56 2014-07-18 1 18 56 2014-07-15 1 19 56 2014-07-15 2
Я попробовал следующий код:
SELECT tu.email, ta.appointment_id, ta.user_id, ta.date, ta.time, ta.recur_type, 0 recursive FROM tbl_appointment ta LEFT JOIN tbl_user tu ON ta.user_id = tu.user_id WHERE 1 AND YEAR(ta.date) = '2014' AND MONTH(ta.date) = '06' AND ta.user_id = 56 UNION ALL SELECT tu.email, ta.appointment_id, ta.user_id, ta.date, ta.time, ta.recur_type, 1 recursive FROM tbl_appointment ta LEFT JOIN tbl_user tu ON ta.user_id = tu.user_id WHERE 1 AND recur_type = '2' AND ta.user_id = 56 UNION ALL SELECT tu.email, ta.appointment_id, ta.user_id, ta.date, ta.time, ta.recur_type, 2 recursive FROM tbl_appointment ta LEFT JOIN tbl_user tu ON ta.user_id = tu.user_id WHERE 1 AND recur_type = '1' AND ta.user_id = 56 ORDER BY date DESC, time
Как удовлетворить требования выше?
Используя запрос для каждого типа рекурсии, объединяются вместе.
Еженедельные и ежемесячные рекурсии используют пару кросс-присоединенных запросов для создания диапазона чисел для добавления к дате. Это справляется с 1000 повторными встречами, но легко расширяется до большего (если назначения хотят повторить более 20 лет).
SELECT a.appoinemnt_id, a.user_id, a.recur_type, a.date AS appoint_date FROM tbl_appointment a WHERE a.recur_type = 0 HAVING appoint_date BETWEEN '2014-07-01' AND '2014-07-31' UNION SELECT a.appoinemnt_id, a.user_id, a.recur_type, DATE_ADD(a.date, INTERVAL units.i + tens.i * 10 WEEK) AS appoint_date FROM tbl_appointment a CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)units CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)tens WHERE a.recur_type = 1 HAVING appoint_date BETWEEN '2014-07-01' AND '2014-07-31' UNION SELECT a.appoinemnt_id, a.user_id, a.recur_type, DATE_ADD(a.date, INTERVAL units.i + tens.i * 10 MONTH) AS appoint_date FROM tbl_appointment a CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)units CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)tens WHERE a.recur_type = 2 HAVING appoint_date BETWEEN '2014-07-01' AND '2014-07-31'
SQL скрипка для этого здесь: –