Мы будем в основном динамически генерировать все необходимые даты в самом запросе.А затем используйте этот набор результатов для Вставить в таблицу reservations
.
Я изменил столбец id
на Первичный ключ и Автоинкремент (как и должно быть).
В Производная таблица , мы будем использовать генератор чисел от 0 до 4, так как может быть максимум 5 сред (и других рабочих дней) в месяце.
Теперь мы попытаемся получитьпервое воскресенье требуемого месяца.Для этого мы сначала создадим дату, соответствующую первой дате месяца, используя значения входных переменных для месяца и года:
STR_TO_DATE(CONCAT('2018','11','01'), '%Y%c%d')
Concat('2018','11','01')
в основном генерирует строку 20181101
.Затем мы можем использовать функцию Str_to_date()
, чтобы преобразовать ее в MySQL формат даты .Мы могли бы использовать функцию Concat()
напрямую, чтобы получить в формате YYYY-MM-DD
;но этот подход должен быть надежным в случае, если входной месяц равен 9
вместо 09
.
Теперь мы будем использовать различные функции Datetime для определения nth Среда.Я расширил ответ, который изначально был дан здесь: https://stackoverflow.com/a/13405764/2469308
Таблица генератора чисел поможет нам при расчете 1-й, 2-й, 3-й среды и т. Д. Мы можем получить первую среду, добавив 3 числа.дней до первого воскресенья.После этого мы обычно добавляем 7 дней каждый раз, чтобы получить следующую среду в месяце.
В конечном итоге мы будем использовать все эти даты и AddTime()
к ним для определения var_start
и var_end
соответственно.Также есть вероятность, что в 5-й день он может перейти в следующий месяц.Поэтому мы отфильтруем их, используя WHERE MONTH(..) .. AND YEAR(..) ..
условия.
Наконец, оператор INSERT INTO.. SELECT
будет использоваться для вставки в таблицу reservations
.
Схема (MySQL v5.7) Вид на БД Fiddle
create table reservations (
id bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT,
var_start datetime NOT NULL,
var_end datetime NOT NULL
);
/*
var_day = "3" // Wednesday
var_month = "11" // November
var_year = "2018"
var_start = "11:00” // 11 am
var_end = "13:00” // 1 pm
*/
Запрос # 1
INSERT INTO reservations (var_start, var_end)
SELECT
ADDTIME(dates.nth_date, '11:00') AS var_start,
ADDTIME(dates.nth_date, '13:00') AS var_end
FROM
(
SELECT
STR_TO_DATE(CONCAT('2018','11','01'), '%Y%c%d') +
INTERVAL (6 -
WEEKDAY(STR_TO_DATE(CONCAT('2018','11','01'), '%Y%c%d')) +
3 +
(7*nth)) DAY AS nth_date
FROM
(SELECT 0 AS nth UNION ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4) AS num_gen
) AS dates
WHERE MONTH(dates.nth_date) = 11 AND
YEAR(dates.nth_date) = 2018;
Запрос # 2
SELECT * FROM reservations;
| id | var_start | var_end |
| --- | ------------------- | ------------------- |
| 1 | 2018-11-07 11:00:00 | 2018-11-07 13:00:00 |
| 2 | 2018-11-14 11:00:00 | 2018-11-14 13:00:00 |
| 3 | 2018-11-21 11:00:00 | 2018-11-21 13:00:00 |
| 4 | 2018-11-28 11:00:00 | 2018-11-28 13:00:00 |
В терминах входных переменных (с префиксом :
для параметрических запросов) запрос будет выглядеть следующим образом:
INSERT INTO reservations (var_start, var_end)
SELECT
ADDTIME(dates.nth_date, :var_start) AS var_start,
ADDTIME(dates.nth_date, :var_end) AS var_end
FROM
(
SELECT
STR_TO_DATE(CONCAT(:var_year,:var_month,'01'), '%Y%c%d') +
INTERVAL (6 -
WEEKDAY(STR_TO_DATE(CONCAT(:var_year,:var_month,'01'), '%Y%c%d')) +
:var_day +
(7*nth)) DAY AS nth_date
FROM
(SELECT 0 AS nth UNION ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4) AS num_gen
) AS dates
WHERE MONTH(dates.nth_date) = :var_month AND
YEAR(dates.nth_date) = :var_year;