Php 使用日历表填补日期范围查询中缺少的空白

Php 使用日历表填补日期范围查询中缺少的空白,php,mysql,Php,Mysql,我使用下面的查询提取某个日期范围的产品总价格,但是在没有销售的日期,我仍然希望显示日期,但值为0 我已经创建了一个日期范围很大的日历表,但还没有找到最好的方法,我所做的一切都错过了没有销售的日子 下面是我正在使用的查询(没有日历表): 我尝试使用的日历表只包含从2010-01-01到2014-12-30的日期范围列表(calendar.date是table.row) 任何帮助都将是惊人的 谢谢 也许这段代码会有所帮助,而不是在需要的地方添加注释。它接受一个数组(假设它来自db)并替换缺少的日期:

我使用下面的查询提取某个日期范围的产品总价格,但是在没有销售的日期,我仍然希望显示日期,但值为0

我已经创建了一个日期范围很大的日历表,但还没有找到最好的方法,我所做的一切都错过了没有销售的日子

下面是我正在使用的查询(没有日历表):

我尝试使用的日历表只包含从2010-01-01到2014-12-30的日期范围列表(calendar.date是table.row)

任何帮助都将是惊人的


谢谢

也许这段代码会有所帮助,而不是在需要的地方添加注释。它接受一个数组(假设它来自db)并替换缺少的日期:

<?php 
$sales=Array('2011-09-16 23:59'=>2,'2011-09-17 23:59'=>7,
'2011-09-18 23:59'=>7,'2011-09-19 23:59'=>7,'2011-09-20 23:59'=>7,
'2011-09-21 23:59'=>7,'2011-09-22 23:59'=>7,'2011-09-23 23:59'=>1,
'2011-10-05 23:59'=>4,'2011-10-21 23:59'=>16,'2012-04-22 23:59'=>12);
$no_sale=' | <font color=red>0</font><br>'; 

//initialize the previosly printed date to the previous of the very first date in $sales
$last_printed = date('Y-m-d', strtotime(substr(key($sales),0,10) . " -1 Day")) ;

foreach($sales as $cd => $sales_cnt)
{
  //extract current date    
  $cd = substr($cd,0,10); 
  //get the next day of the last date that was echoed
  $next_of_last_printed = date('Y-m-d', strtotime($last_printed . " +1 Day"));

  //if the current date retrieved from database is next of the last printed
  if($next_of_last_printed  == $cd) 
  {
    echo $cd.' | ', $sales_cnt,'<br>';//then print it
    $last_printed=$cd;//since we print it change the last printed
  }//if
  else
  {     //since current retrieved from db is not valid print a valid date 
        echo $next_of_last_printed ,$no_sale;
        $last_printed = $next_of_last_printed;//since we printed a date set last printed
        while(true)
        {   
            //since we set the last printed then get the next of it
            $next_of_last_printed = date('Y-m-d', strtotime($last_printed . " +1 Day"));
            //if the next we generated is the same with the one retrieved from db
             if($next_of_last_printed ==$cd)  
             {
                echo $cd.' | ', $sales_cnt,'<br>';//then echo this retrieved from db
                $last_printed = $cd;//since we printed a date set last printed  
                break(1);
             }
            //since we got the next date print it  
            echo $next_of_last_printed,$no_sale;
            $last_printed = $next_of_last_printed; //then set last printed

        }//while
    }//else 
}//foreach

?>

您需要日历表上的外部联接。差不多

SELECT c.cal_date, coalesce(t1.price, 0) as total
FROM calendar c
LEFT JOIN (SELECT b.purchase_date::date, sum(price) as price 
           FROM order_products a 
           INNER JOIN order_saved b 
                   ON a.order_id = b.id 
                   AND b.purchase_date BETWEEN '2011-09-16 23:59' AND '2011-10-16 23:59' 
                   AND b.status > 2
                   AND a.usr_id = 'XXXX'
            GROUP BY b.purchase_date) t1 on t1.purchase_date = c.cal_date
WHERE cal_date BETWEEN '2011-09-16 23:59' AND '2011-10-16 23:59' 
ORDER BY c.cal_date

如果您发布DDL(
CREATE TABLE
)语句和最小的
INSERT
语句,这些语句为我们提供了足够的数据来实际测试我们的答案,那么您将获得更好的答案。(编辑您的问题并粘贴DDL和INSERT语句。)

很多次我都遇到同样的问题,不仅仅是日期。。。我的结论是,在数据库中这样做很糟糕,我在表示层(在我的例子中是PHP)中这样做的。但这确实是一个好问题。也许您应该在php中添加这些值,这样就不会使查询变得复杂much@mishu,这正是我的意思:-)如果你对如何用PHP做这件事有什么建议,那就太好了,我只是个大三学生;)这可能会有帮助:很好,因为它是独立于php(语言)的!是的,创建表格非常有帮助,不幸的是大多数时候都没有给出。令人惊讶的是,这就成功了!必须移动一些位。非常感谢你的来电!
SELECT c.cal_date, coalesce(t1.price, 0) as total
FROM calendar c
LEFT JOIN (SELECT b.purchase_date::date, sum(price) as price 
           FROM order_products a 
           INNER JOIN order_saved b 
                   ON a.order_id = b.id 
                   AND b.purchase_date BETWEEN '2011-09-16 23:59' AND '2011-10-16 23:59' 
                   AND b.status > 2
                   AND a.usr_id = 'XXXX'
            GROUP BY b.purchase_date) t1 on t1.purchase_date = c.cal_date
WHERE cal_date BETWEEN '2011-09-16 23:59' AND '2011-10-16 23:59' 
ORDER BY c.cal_date