如何找到第一个低于数据库的日期。 如果这个日期不存在,我需要在数据库中查找日期 - 比今天日期晚30天。我需要比第一个更低的日期。
2017-08-30
2017-08-23
2017-08-16
2017-08-09
2017-08-02
2017-07-26
2017-07-19
例如,我今天的数据是
2017年8月30日
所以我需要在2017-08-30之间找到日期-30天
(将于2017年7月31日)
如果数据库中不存在此数据,我需要采用第一个低于31.07.2017的日期
所以这个日期将是2017-07-26
我试过了:
$lastMonth = date_format(new \Datetime('-30 days'), 'Y-m-d');
for($i= 0; $i<7;){
$parts = explode('-', $lastMonth);
$lastMonth = date('Y-m-d', mktime(0, 0, 0, $parts[1], $parts[2] - $i, $parts[0]));
$query = $this->em->createQuery(
'SELECT sum(psc.score) / COUNT(psc.id) as avgscore, psc.date
FROM AppBundle:PageSpeedScore psc
WHERE psc.projectId = :projectId
AND psc.date = :date
GROUP BY psc.date, psc.projectId
ORDER BY psc.date
'
)->setParameter('projectId', $projectId)
->setParameter('date', $lastMonth);
if(empty($query->getResult())){
$i++;
}else{
$date = $query->getResult();
break;
}
}
这让我回到2017-07-26所以它的工作但是......我认为这不是优雅的方式。 我现在对数据库有很多疑问。我想我可以用一个查询来做到这一点。也许有人可以帮助我并告诉我如何在没有for循环的情况下只在mySQL查询中执行此操作?
答案 0 :(得分:1)
如果我理解正确的话,这段代码应该可以解决问题:
$query = $this->em->createQuery(
'SELECT sum(psc.score) / COUNT(psc.id) as avgscore, psc.date
FROM AppBundle:PageSpeedScore psc
WHERE psc.projectId = :projectId
AND psc.date <= :date AND DATE_ADD(psc.date, 7, 'DAY') >= :date
GROUP BY psc.date, psc.projectId
ORDER BY psc.date DESC')
->setParameter('projectId', $projectId)
->setParameter('date', $lastMonth)
->setMaxResults(1)
->getSingleResult();
您基本上搜索的是等于阈值日期(psc.date <= :date
)且日期少于您的起点日期(DATE_ADD(psc.date, 7, 'DAY') >= :date
)的日期的效果结果。
您按日期按降序排列结果(ORDER BY psc.date DESC
),因此阈值以下的最新日期是结果集中的第一条记录。
然后,您调用->setMaxResults(1)
仅检索此第一条记录并将其与->getSingleResult()
一起返回。如果找不到匹配的结果,getSingleResult将抛出一个NoResultException
,你可以捕获它,然后使用你的默认值。
答案 1 :(得分:0)
删除整个循环并改为执行此操作
SELECT sum(psc.score) / COUNT(psc.id) as avgscore, MAX(psc.date) AS thedate
FROM AppBundle:PageSpeedScore psc
WHERE psc.projectId = :projectId
AND psc.date <= (SELECT DATE_SUB(MAX(`date`), INTERVAL 30 DAY)
FROM AppBundle:PageSpeedScore
WHERE projectId = :projectId
)
您只需要一个查询并绑定您的项目
由于SELECT子句的所有列都有一个聚合函数,因此不需要GROUP BY