Php Mysql查询选择接下来45天内的所有日期(仅限日和月)

Php Mysql查询选择接下来45天内的所有日期(仅限日和月),php,mysql,mysqli,Php,Mysql,Mysqli,我需要选择未来45天内的所有日期(日和月)(不考虑年份)。下面的查询已停止工作。比如,当确实存在数据时,就开始不返回任何行 是否有其他方法执行此查询?如果需要,很乐意检查php循环中的记录 基本上,我需要在接下来的45天内显示所有记录,即使一年过去了 SELECT p.*, c.company FROM products p LEFT JOIN customers c ON c.id = p.id WHERE DATE_FORMAT(

我需要选择未来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
选择
p、 *,
c、 公司
从…起
产品p
左连接
顾客c
在c.id=p.id上
哪里
日期格式(p.service\u DATE,'%m-%d')>=日期格式(CURDATE(),'%m-%d'))

和日期格式(p.service\u DATE,“%m-%d”)我不知道您的原始查询为什么在一列(
service\u DATE
)上使用
DATE\u FORMAT()
,该列已存储在MySQL日期类型中,用于范围比较。它也不能使用任何索引(如果已定义)

您只需在日期上加/减
间隔

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
选择
p、 *,
c、 公司
从…起
产品p
左连接
顾客c
在c.id=p.id上
哪里
p、 服务日期>=CURDATE()

解决这个问题的最好办法是使用。困难的部分是在年底后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
当DAYOFYEAR('2018-12-31')-DAYOFYEAR(NOW())<45时的情况
DAYOFYEAR(p.service_date)介于DAYOFYEAR(NOW())和DAYOFYEAR('2018-12-31')之间,或
DAYOFYEAR(p.service_date)介于1和DAYOFYEAR(现在()+间隔45天)之间
其他的
DAYOFYEAR(p.service_date)介于DAYOFYEAR(NOW())和DAYOFYEAR(NOW()+间隔45天)之间
终止
然后,您的完整查询应如下所示:

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
选择
p、 *,
c、 公司
从…起
产品p
左连接
顾客c
在c.id=p.id上
哪里
(当DAYOFYEAR('2018-12-31')-DAYOFYEAR(NOW())<45时的情况)
DAYOFYEAR(p.service_date)介于DAYOFYEAR(NOW())和DAYOFYEAR('2018-12-31')之间,或
DAYOFYEAR(p.service_date)介于1和DAYOFYEAR(现在()+间隔45天)之间
其他的
DAYOFYEAR(p.service_date)介于DAYOFYEAR(NOW())和DAYOFYEAR(NOW()+间隔45天)之间
(完)
和c.email_service=1
订购人
p、 服务日期ASC

如果您担心闰年,您可以将
DAYOFYEAR('2018-12-31')
更改为
DAYOFYEAR(CONCAT(YEAR(NOW),'-12-31'))
使用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'";
    }
}

service\u date
列数据是什么样子的?它的数据类型是什么。只有一个标准的日期字段-即“2017-11-29”在该查询中仍将在接下来的45天内,因为我不关心年份。请看,我使用的是日期格式,因此我可以忽略年份。此查询将仅在未来45天内查看dd mm yy。我需要在接下来的45天内看到日期,即使年份已经过期。@Jeff你所说的年份已经过期是什么意思。我的查询将工作45天+当前日期,与年份无关。因此,我希望在接下来的45天内选择日期与年份无关的记录就是一个例子。”“2017-11-29”和“2018-11-29”上述内容将始终基于当前年份进行查询。@Jeff尝试运行查询。我不明白为什么我的查询只有一年有效。除非表中的数据不是真正的日期类型。最好是拿出一堆小样本数据来说明确切的问题。你可以在这里设置它:Hi@nick-有一个错误,但是我不知道我是否正确地组合了查询。你的SQL语法有一个错误;检查与您的MariaDB服务器版本相对应的手册,了解第6行“CASE WHEN DAYOFYEAR('2018-12-31')-DAYOFYEAR(NOW())<45 THEN DAYOFYEAR”附近使用的正确语法完整查询应该是什么样子。“我不能让它工作了?”杰夫对回复慢表示抱歉——他正在睡觉。我已经添加了完整查询应该是什么样子的,尽管我看到您已经自己解决了这个问题。
    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