Mysql запрос выбрать все даты (только день и месяц) в течение следующих 45 дней - PullRequest
0 голосов
/ 24 ноября 2018

Мне нужно выбрать все даты (день и месяц) в течение следующих 45 дней (независимо от года).Приведенный ниже запрос перестал работать.Как буквально начал возвращать без строк, когда там определенно есть данные.

Есть ли другой способ сделать этот запрос?Рад проверить записи в цикле php, если это необходимо.

По сути, мне нужно показать все записи в течение следующих 45 дней, даже если год истек.

SELECT
   p.*,
   c.company 
FROM
   products p 
   LEFT JOIN
      customers c 
      ON c.id = p.id 
WHERE
   DATE_FORMAT(p.service_date, '%m-%d') >= DATE_FORMAT(CURDATE(), '%m-%d') 
   AND DATE_FORMAT(p.service_date, '%m-%d') <= DATE_FORMAT((CURDATE() + INTERVAL 45 DAY), '%m-%d') 
   AND c.email_service = 1 
ORDER BY
   p.service_date ASC

Ответы [ 3 ]

0 голосов
/ 24 ноября 2018

Лучший способ решить эту проблему - использовать DAYOFYEAR.Трудной частью является случай, когда вы находитесь в течение 45 дней после окончания года, и в этом случае вы должны разделить чек, чтобы увидеть, находится ли дата между настоящим моментом и концом года или началом года.а сейчас + 45 дней;в противном случае вы просто проверяете, находится ли день года между сейчас и сейчас + 45 дней.Попробуйте заменить ваше условие следующим образом:

CASE WHEN DAYOFYEAR('2018-12-31')-DAYOFYEAR(NOW()) < 45 THEN
         DAYOFYEAR(p.service_date) BETWEEN DAYOFYEAR(NOW()) AND DAYOFYEAR('2018-12-31') OR
         DAYOFYEAR(p.service_date) BETWEEN 1 AND DAYOFYEAR(NOW() + INTERVAL 45 DAY)
     ELSE
         DAYOFYEAR(p.service_date) BETWEEN DAYOFYEAR(NOW()) AND DAYOFYEAR(NOW() + INTERVAL 45 DAY)
     END

Ваш полный запрос должен выглядеть следующим образом:

SELECT
   p.*,
   c.company 
FROM
   products p 
   LEFT JOIN
      customers c 
      ON c.id = p.id 
WHERE
    (CASE WHEN DAYOFYEAR('2018-12-31')-DAYOFYEAR(NOW()) < 45 THEN
              DAYOFYEAR(p.service_date) BETWEEN DAYOFYEAR(NOW()) AND DAYOFYEAR('2018-12-31') OR
              DAYOFYEAR(p.service_date) BETWEEN 1 AND DAYOFYEAR(NOW() + INTERVAL 45 DAY)
          ELSE
              DAYOFYEAR(p.service_date) BETWEEN DAYOFYEAR(NOW()) AND DAYOFYEAR(NOW() + INTERVAL 45 DAY)
          END)
    AND c.email_service = 1 
ORDER BY
    p.service_date ASC

Если вы беспокоитесь о високосных годах, вы можете изменить DAYOFYEAR('2018-12-31') наDAYOFYEAR(CONCAT(YEAR(NOW), '-12-31'))

0 голосов
/ 24 ноября 2018

Работал с php

// Get the dates m-d for the next 45 days
for ($i = 0; $i <= 45; $i++) {
    $days = '+' . $i . ' days';
    $date = date('m-d', strtotime($days));
    if ($i != 45) {
        $DateQuery .= "'$date',";
    } else {
        $DateQuery .= "'$date'";
    }
}

и вставлял нужные мне даты прямо в запрос

    SELECT
       p.*,
       c.company 
    FROM
       products p 
       LEFT JOIN
          customers c 
          ON c.id = p.id 
    WHERE
       DATE_FORMAT(p.service_date, '%m-%d') IN 
       (
           $DateQuery
       )
       AND c.email_service = 1 
    ORDER BY
       p.service_date ASC
0 голосов
/ 24 ноября 2018

Я не знаю, почему ваш исходный запрос использовал Date_Format() для столбца (service_date), уже сохраненного в типе MySQL Date, для сравнения диапазонов.Он также не может использовать индексирование (если оно определено).

Вам просто нужно добавить / вычесть Interval к дате:

SELECT
   p.*,
   c.company 
FROM
   products p 
   LEFT JOIN
      customers c 
      ON c.id = p.id 
WHERE
   p.service_date >= CURDATE() 
   AND p.service_date <= (CURDATE() + INTERVAL 45 DAY) 
   AND c.email_service = 1 
ORDER BY
   p.service_date ASC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...