Дата в пределах какого-то периода

У меня есть следующая таблица проектов с их периодами активности (периоды определены датами ОТ и ДО):

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-запрос (функция), который вернет истину / ложь, если данный проект был активен в определенную дату (указана дата в некоторых периодах активности проекта).

Здорово! Итак, у вас есть пробовал что-нибудь?

Obsidian Age 21.11.2018 00:39

Подсказка: WHERE и некоторые сравнения дат.

Gordon Linoff 21.11.2018 00:41

Да, я что-то пробовал, но у меня проблема с произвольным количеством периодов. Если количество периодов известно, то это проще простого, но как проверить в пределах неизвестного количества периодов.

sbrbot 21.11.2018 00:44

Намек: SELECT CASE COUNT(*) WHEN > 0 THEN TRUE ELSE FALSE FROM project WHERE '2018-11-21' BETWEEN(ActiveFrom, ActiveTo)

Antony Gibbs 21.11.2018 01:04

Спасибо @AntonyGibbs, это хороший намек: ВЫБЕРИТЕ СЧЕТЧИК (*) ИЗ проектов, ГДЕ projId = 20 И '2018-01-21' МЕЖДУ ActiveFrom И ActiveTo

sbrbot 21.11.2018 01:17

Спасибо ... но я вижу, что забыл поставить GROUP BY ProjectId в конце - он необходим для использования COUNT()

Antony Gibbs 21.11.2018 01:20

@AntonyGibbs GROUP BY не нужна, я отфильтровал Project с WHERE ProjID = 20 и использовал COUNT (*) для всего набора результатов (GROUP BY тогда не требуется)

sbrbot 21.11.2018 01:28
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
6
7
90
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Эта функция должна делать то, что вы хотите. Он полагается на то, что 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

Демо на dbfiddle

Вот и все, я не привык использовать BETWEEN в качестве логического теста в SELECT (я всегда использовал его в предложении WHERE). Ребята отрицательно отметили мой вопрос, хотя он не так прост, как кажется.

sbrbot 21.11.2018 00:59

@sbrbot согласился, неизвестное количество точек действительно усложняет задачу. Тот факт, что MySQL обрабатывает логические значения как целые числа, позволяет найти относительно более простое решение вместо того, чтобы перебирать все периоды в цикле. Обратите внимание: поскольку в конечном итоге это однострочный файл, вам, вероятно, не нужно заключать его в функцию.

Nick 21.11.2018 01:02

Точно, здесь @Nick использовал MAX, чтобы вернуть 1, если запрошенная дата находится как минимум в пределах одного периода (если нет перекрытия, то существует только одна 1, но неперекрывающиеся периоды не были указаны). Также я хотел избежать зацикливания периодов внутри функции, поэтому я изменил этот запрос (а затем функцию). Однако я думаю, что ребята недооценили вопрос.

sbrbot 21.11.2018 01:10

Другие вопросы по теме