У меня есть следующая таблица проектов с их периодами активности (периоды определены датами ОТ и ДО):
ID | ProjID | ActiveFrom | ActiveTo
===+========+============+============
1 | 20 | 2018-01-01 | 2018-01-20
2 | 20 | 2018-02-05 | 2018-02-12
3 | 20 | 2018-02-20 | 2018-02-27
4 | 30 | 2018-01-15 | 2018-02-15
Конечно, у проекта может быть произвольное количество периодов активности.
Мне нужен SQL-запрос (функция), который вернет истину / ложь, если данный проект был активен в определенную дату (указана дата в некоторых периодах активности проекта).
Подсказка: WHERE и некоторые сравнения дат.
Да, я что-то пробовал, но у меня проблема с произвольным количеством периодов. Если количество периодов известно, то это проще простого, но как проверить в пределах неизвестного количества периодов.
Намек: SELECT CASE COUNT(*) WHEN > 0 THEN TRUE ELSE FALSE FROM project WHERE '2018-11-21' BETWEEN(ActiveFrom, ActiveTo)
Спасибо @AntonyGibbs, это хороший намек: ВЫБЕРИТЕ СЧЕТЧИК (*) ИЗ проектов, ГДЕ projId = 20 И '2018-01-21' МЕЖДУ ActiveFrom И ActiveTo
Спасибо ... но я вижу, что забыл поставить GROUP BY ProjectId в конце - он необходим для использования COUNT()
@AntonyGibbs GROUP BY не нужна, я отфильтровал Project с WHERE ProjID = 20 и использовал COUNT (*) для всего набора результатов (GROUP BY тогда не требуется)






Эта функция должна делать то, что вы хотите. Он полагается на то, что MySQL обрабатывает логические результаты как 1 или 0 в числовом контексте, поэтому вызов MAX фактически становится OR всех условий.
CREATE FUNCTION check_activity(project_id INT, check_date DATE)
RETURNS BOOLEAN
DETERMINISTIC
BEGIN
RETURN (SELECT MAX(check_date BETWEEN ActiveFrom AND ActiveTo) FROM projects WHERE ProjId = project_id);
END
SELECT check_activity(20, '2018-01-10'), check_activity(20, '2018-02-01')
Вывод
check_activity(20, '2018-01-10') check_activity(20, '2018-02-01')
1 0
Вот и все, я не привык использовать BETWEEN в качестве логического теста в SELECT (я всегда использовал его в предложении WHERE). Ребята отрицательно отметили мой вопрос, хотя он не так прост, как кажется.
@sbrbot согласился, неизвестное количество точек действительно усложняет задачу. Тот факт, что MySQL обрабатывает логические значения как целые числа, позволяет найти относительно более простое решение вместо того, чтобы перебирать все периоды в цикле. Обратите внимание: поскольку в конечном итоге это однострочный файл, вам, вероятно, не нужно заключать его в функцию.
Точно, здесь @Nick использовал MAX, чтобы вернуть 1, если запрошенная дата находится как минимум в пределах одного периода (если нет перекрытия, то существует только одна 1, но неперекрывающиеся периоды не были указаны). Также я хотел избежать зацикливания периодов внутри функции, поэтому я изменил этот запрос (а затем функцию). Однако я думаю, что ребята недооценили вопрос.
Здорово! Итак, у вас есть пробовал что-нибудь?