Как отобразить текущие месячные проекты в списке, где дата текущего месяца находится между A и B при пролонгации нового года - PullRequest
0 голосов
/ 02 января 2019

В прошлом году я установил систему управления проектами, но теперь, когда мы находимся в новом году, я был немного в своей заднице из-за некоторого кодирования новичка (от меня) :)

Так что теперь яочень нужна ваша помощь, чтобы понять, как исправить это раз и навсегда.

Ошибка:

Основная проблема сейчас в том, что год переворачивается, сейчас мой SQLзапрос не понимает, что месяц нового года (1) больше текущего года (12), который затем не отображает нужные проекты в списке.

Есть идеи?Заранее спасибо!

Это мой текущий SQL-запрос:

SELECT *
FROM projects
WHERE MONTH(CURDATE()) between MONTH(project_start) and MONTH(project_delivery)
AND YEAR(CURDATE()) between YEAR(project_start) and YEAR(project_delivery)
order by project_id

Это необработанная структура табличных проектов:

Project_id projet_start projet_delivery
1          2018-12-20   2018-12-22
2          2018-12-25   2018-12-29
3          2018-12-28   2018-12-28
4          2018-12-30   2019-01-22

Ответы [ 2 ]

0 голосов
/ 02 января 2019

МЕЖДУ работает на фактические даты:

SELECT *
FROM projects
WHERE CURDATE() between project_start and project_delivery
order by project_id

Если вы хотите все от месяца (детализация месяца), а не от дня:

SELECT *
FROM projects
WHERE CURDATE() between DATE_SUB(project_start, INTERVAL DAY(project_start)-1 DAY) and 
  DATE_ADD(DATE_SUB(project_delivery, INTERVAL DAY(project_delivery) DAY), INTERVAL 1 MONTH)
order by project_id

Таким образом, если бы проект начался 5 декабря и закончился 19 января, это дало бы все в период с 1 декабря по 31 января. Имейте в виду, однако, что если какая-либо дата 31 января также имеет компонент времени (то есть позже полуночи), это будет означать, что она немного позже этой даты окончания и не будет отображаться.

Прокомментируйте, если это так, и вам нужна помощь в решении проблемы (проще всего не использовать BETWEEN, потому что он всегда включительно на каждом конце, используйте <, который является эксклюзивным)

Обновление: проекты, которые имели некоторую активность в этом месяце, то есть проект, который:

  • начался раньше, закончился во время
  • началось раньше, закончилось после
  • начался во время, закончился во время
  • начался во время, закончился после

Общим для всех является то, что дата начала проекта - до конца этого месяца, а также дата окончания проекта - после первого месяца этого месяца

SELECT *
FROM projects
WHERE 
  --started before the end of this month
  project_start < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL DAY(CURDATE()) - 1 DAY), INTERVAL 1 MONTH) AND
  --ended after the start of this month
  project_delivery > DATE_SUB(CURDATE(), INTERVAL DAY(CURDATE()) DAY) 

order by project_id

Выполнение DATE_SUB(CURDATE(), INTERVAL DAY(CURDATE()) DAY) - довольно запутанный способ написания «вычесть номер текущего дня из текущей даты», т.е. 2019-01-02 minus 2 -> 2018-12-31. Мы ищем даты > это (чтобы не включать его)

Аналогичным образом, DATE_ADD(DATE_SUB(CURDATE(), INTERVAL DAY(CURDATE()) - 1 DAY), INTERVAL 1 MONTH) Снимает текущую дату, подпрограммы DAY-1 (т.е. только 1 на этот раз, а не 2), чтобы достичь 1-го числа этого месяца, а затем добавляет месяц, чтобы перейти к первому из следующего месяца. 2019-01-02 -> 2019-01-01 -> 2019-02-01. Опять < это так эксклюзивно

Существует ошибка при переходе в другую сторону (добавьте месяц, а затем добавьте день), если вы, например, 31 января, и сначала добавляете месяц - 31 февраля не будет, поэтому mysql завершит свою работу 28 числа фев, затем саб 31 дней выходных, давая дату, которая не является концом января (то есть 28 января)

0 голосов
/ 02 января 2019

Просто используйте сравнения дат:

select p.*
from projects p
where curdate() >= project_start and
      curdate() <= project_delivery;

Я не уверен, почему вы хотите разбить даты на их компоненты времени. Тем не менее, совершенно не нужно их сравнивать.

Если вы хотите просто выполнить сравнение на уровне месяца, то один из методов - преобразовать значения в месяцы:

select p.*
from projects p
where year(curdate()) * 12 + month(curdate()) >=  year(project_start) * 12 + month(project_start) and
      year(curdate()) * 12 + month(curdate()) <= year(project_delivery) * 12 + month(project_delivery);

Либо просто переместите даты в начало месяцев:

select p.*
from projects p
where curdate() >= project_start + interval 1 - day(project_start) day and
      curdate() < ( project_delivery + interval (1 - day(project_delivery) day) + interval 1 month;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...