2017-08-31 108 views
-1

如何找到比数据库中给出的第一个更低的日期。 如果这个日期不存在,我需要查找日期 - 比数据库中的日期还晚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日

所以我需要找到日期-30天,从2017年8月30日

(将会是31.07.2017)

如果在数据库中不存在这个数据我需要第一下日期比2017年7月31日

所以这个日期将是2017年7月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; 
     } 
     } 

This return me 2017-07-26所以它的工作,但...这是不是优雅的方式来做到这一点我认为。 我现在对数据库有很多查询。我想我可以用一个查询来完成。也许有人可以帮助我,告诉我如何在没有for循环的情况下在mySQL查询中执行此操作?

+0

当前代码的结果是什么? –

+0

当前代码返回我所需要的,但它不是优雅的方式我想要找到更多的性能方式像一个查询 – johnyT

回答

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)早7天以下的日期。

您可以按日期降序排列结果(ORDER BY psc.date DESC),因此阈值以下的最新日期是结果集中的第一条记录。

然后您拨打电话->setMaxResults(1)只检索这第一条记录,并返回->getSingleResult()。如果没有找到匹配的结果,getSingleResult将会抛出一个你可以捕获的NoResultException,然后改用你的默认值。

+0

确定它工作正常,但我怎么能保证这只厕所只有7天。如果我没有找到比给定日期低7天的日期,我想返回默认值。如何在此查询中只搜索7天? – johnyT

+0

检查我更新的答案。我包含了附加条件AND DATE_ADD(psc.date,7,'DAY')> =:date' –

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

+0

确定但INTERVAL现在不工作在symfony查询造物主 – johnyT

+0

我不知道symfony在所有。这是标准的MySQL语法。难道你不能强迫SQL而不是使用“创造者”? –

相关问题