Mysql使用where in子句或与数组中的日期最接近的日期来查找日期


Mysql find dates using where in clause, or dates nearest to those in array

我有以下代码和查询:

//$month is an array of datetime objects
foreach($month as $key => $indMonth){
    $formattedMonth[] = $month[$key]->format('Y-m-d');
}
$formattedMonths = implode("','",$formattedMonth);
$query = "SELECT id,date FROM table WHERE date in ('$formattedMonths') ORDER by date DESC";

该数据库保存了过去450天的日期,但并不完美,还有一些缺失的日期。脚本的目的是从一个月的当前日期检索数据,然后从前五个月的相应日期检索数据。但我需要一个故障保护,以防日期丢失。

如何修改此查询,使其在查询的"where in"部分中选择日期,或者在数组中查找最接近该特定日期的日期?

在查询中这样做是最好的,还是我最好返回一个更完整的数据集,然后使用PHP来确定我想要的日期是否可用?

MySQL提供了一些不错的日期算法。例如,如果您的日期为'2015-11-10'(2015年11月10日),则您可以在三个月前使用以下表达式获得同一天:

'2015-11-10` - INTERVAL 3 MONTH

这将击退'2015-08-10',这正是您想要的。

这种日期算法即使在较长和较短的月份以及闰年也可以预测。例如,

'2015-03-31' - INTERVAL 1 MONTH, '2016-03-31' - INTERVAL 1 MONTH

如您所期望的那样返回'2015-02-28', '2016-02-29'。和

'2015-03-31' - INTERVAL 2 MONTH, '2016-03-31' - INTERVAL 2 MONTH

返回CCD_ 4。完美的

现在,只有您可以决定这种可预测的行为对于您的应用程序是否正确:只有您知道您想在月底前五个月的数据中做什么。

让我们假设它是正确的,然后继续。下面是一个子查询,可以用来生成一个由六个日期组成的序列,每个月有一天截止到今天。

    SELECT CURDATE() - INTERVAL seq.seq MONTH day_of_month
      FROM ( SELECT 0 AS seq UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL
             SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 6) seq

我们可以将这个小查询用作子查询,并将其LEFT JOIN用于您的数据。工作原理如下:

 SELECT id, day_of_month
   FROM (
      SELECT CURDATE() - INTERVAL seq.seq MONTH day_of_month
        FROM ( SELECT 0 AS seq UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL
               SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 6) seq
        ) days
   LEFT JOIN table ON table.date = days.day_of_month

这是一种很酷的方法,因为即使table. 中没有匹配的内容,列表中每个日期的结果集中也总是至少有一行

最近的日期变得有点多毛。可以编写这样的查询。但是MySQL缺少WITH子句,所以查询的重复性非常高。