我有以下代码和查询:
//$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查看我想要的日期是否可用?
答案 0 :(得分:1)
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
返回'2015-03-31', '2016-03-31'
。完美。
现在,只有您可以确定应用程序的可预测行为是否正确:只有您知道要对前五个月的数据做什么,有关日期即将到月底。
让我们假设它正确并继续前进。这是一个子查询,可用于生成六个日期的序列,每月一天结束。
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.
1}}中没有任何匹配项,您也总是会在结果集中为列表中的每个日期获得至少一行p>
最近的日期变得有点毛茸茸。可以编写这样的查询。但是MySQL缺少WITH
子句,所以查询是重复的。