Я программирую расписание офиса.
У меня есть таблица users
, в которой у каждого пользователя есть регулярное расписание hreg
с понедельника по пятницу.
У меня есть таблица hleave
, в которую я ввожу код отпускадля дат, когда пользователь не в офисе.
Таблица hleave
:
hleave_id user dateStart dateEnd leaveCode
int(11)PK int(11)FK date date int(11)FK
1 5 2019-02-11 2019-02-13 1
2 1 2019-02-28 2019-02-28 1
3 3 2019-02-26 2019-02-28 2
Таблица users
:
user_id firstName lastName link_team_id link_hreg_id
int(11)PK varchar varchar int(11)FK int(11)FK
1 Bob Smith 1 1
2 Alice Fraser 1 1
3 Jenny Summers 1 1
4 Carl Raisman 1 1
5 Roger Wayne 1 1
Таблица teams
:
team_id teamName
int(11)PK varchar
1 team 1
2 team 2
3 team 3
Таблица hreg
:
hreg_id weekStart weekEnd
int(11)PK int(11) int(11)
1 1 5
2 1 4
3 2 5
Таблица leave_codes
:
code_id codeName
int(11)PK varchar
1 A
2 B
3 C
4 D
Если есть запись с указанием диапазона дат, которая либо начинает этотнеделю, заканчивается на этой неделе или начинается до этой недели и заканчивается после этой недели, я хочу показать код отпуска.
Если нет, я хочу отобразить обычное расписание пользователя "работает".Например:
Monday Tuesday Wednesday Thursday Friday
BOB working working working A working
ALICE working working working working working
JENNY working B B B working
CARL working working working working working
Вот мой запрос для TEAM # 1 (я заменил переменные $ понедельник и $ пятница на реальные даты для ясности):
SELECT
users.firstName,
users.lastName,
users.link_team_id,
users.link_hreg_id,
hreg.weekStart,
hreg.weekEnd,
leave_codes.codeName,
hleave.dateStart,
hleave.dateEnd
FROM users
LEFT JOIN hleave ON hleave.user = users.user_id
JOIN teams ON users.link_team_id = teams.team_id
JOIN hreg ON users.link_hreg_id = hreg.hreg_id
LEFT JOIN leave_codes ON hleave.leaveCode = leave_codes.code_id
WHERE
(CASE
WHEN (hleave.dateStart BETWEEN '2019-02-25' AND '2019-03-01')
THEN (users.link_team_id = 1)
WHEN (hleave.dateEnd BETWEEN '2019-02-25' AND '2019-03-01')
THEN (users.link_team_id = 1)
WHEN (hleave.dateStart < '2019-02-25' AND hleave.dateEnd > '2019-03-01')
THEN (users.link_team_id = 1)
WHEN (hleave.dateStart IS NULL AND hleave.dateEnd IS NULL)
THEN (users.link_team_id = 1)
END)
Результаты:
firstName lastName link_team_id link_hreg_id weekStart weekEnd codeName dateStart dateEnd
Bob Smith 1 1 1 5 A 2019-02-28 2019-02-28
Alice Fraser 1 1 1 5 NULL NULL NULL
Jenny Summers 1 1 1 5 B 2019-02-26 2019-02-28
Carl Raisman 1 1 1 5 NULL NULL NULL
Этот запрос работает.Я получаю codeName
, dateStart
и dateEnd
для пользователя, если это произойдет на этой неделе.Если dateStart
и dateEnd
равны NULL, я по-прежнему получаю пользователя firstName
, lastName
и hreg
, поэтому я могу отображать их на веб-сайте как работающие.
Пока все хорошо, но у меня проблема.Когда dateStart < '2019-02-25'
и dateEnd < '2019-03-01'
(то есть, если отпуск произошел до этой недели), я ничего не получаю для этого пользователя, поскольку диапазон дат проверяется как ЛОЖЬ, и он также не равен NULL.Например, если у Роджера был отпуск с 2019-02-11 по 2019-02-13, Роджер не включается в набор результатов.
То же самое относится и к диапазону дат в будущем: dateStart > '2019-02-25'
и dateEnd> '2019-03-01'
.
Каков наилучший способ добиться этого?Я попытался CASE WHEN в предложении SELECT для точного определения дат, которые я хочу выбрать, но результат тот же.Мне либо нужно выбрать по-другому, либо превратить записи, проверяющие как ЛОЖЬ, в НЕДЕЙСТВИТЕЛЬНЫЙ?