【问题标题】:MySQL - fill missing dates [duplicate]MySQL - 填补缺失的日期[重复]
【发布时间】:2016-07-23 22:59:21
【问题描述】:

我有这个查询,我想用一些值填充缺失的日期(例如零......)

SELECT date, SUM(val1) as sum_val  
FROM table1  
WHERE date BETWEEN '2016-03-04' AND '2016-03-10'  
GROUP BY date

结果如下:

|--------------------------  
|date, sum_val  
|--------------------------  
|2016-03-04, 21568  
|--------------------------  
|2016-03-05, 14789  
|--------------------------  
|2016-03-08, 20568  
|--------------------------  
|2016-03-10, 5841  
|--------------------------

如何使用零值填充缺失的日期?有人有想法吗?

我需要这些数据用于图表预览。

【问题讨论】:

  • 您需要使用带有日历的附加表或过程来制作具有日期范围的临时表
  • 没有其他方法可以做到这一点吗?
  • 只循环一个月,如果它与你的存在日期匹配,则不需要插入数据,而是添加0。
  • 您可以手动选择每个日期,而不是使用纯 sql - 否
  • @Heril Muratovic 在 mysql - 没有。但是你可以在 php 中做到这一点

标签: php mysql charts


【解决方案1】:

你可以试试这个 PHP 循环:

$date1 = Your_first_date_value;
$date2 = Your_limit_date;
for ($d1 = $date1; d1<=$date2; strtotime("+1 day", strtotime($d1))) {
    //Fill in values
}

strtotime("+1 day", strtotime($date1))$date1 的当前值增加 1 天,直到等于 $date2

当日期没有值时为零,如果日期存在,则根据MySQL结果取和。

【讨论】:

  • @downvoter 为什么??????它在我的项目中为我工作
  • 我会试试这个...
  • $date1 和 $date2 应该是 strtotime 值吗?
  • 你有什么错误吗?输出是什么? STRTOTIME:The function expects to be given a string containing an English date format and will try to parse that format into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 UTC), relative to the timestamp given in now, or the current time if now is not supplied.
【解决方案2】:

一般来说,您可以在 MySQL 中使用以下方法生成一系列 N 个整数:

    select (@i:=@i+1)-1 as `myval` from someTable,(SELECT @i:=0) gen_sub limit N

请注意,您加入的表 (someTable) 必须至少有 N 行。 上面的 -1 是为了使其基数为零...删除它,您将得到 1 ,2,3 表示 N=3。

您可以将这些整数输入 DATE_ADD 函数以将其转换为一系列日期。为了更容易理解,让我们为日期使用一些用户变量。

SET @date_min = '2016-03-04';
SET @date_max = '2016-03-10';

select DATE_ADD(@date_min, INTERVAL (@i:=@i+1)-1 DAY) as `date`
from information_schema.columns,(SELECT @i:=0) gen_sub
where DATE_ADD(@date_min,INTERVAL @i DAY) BETWEEN @date_min AND @date_max

这将返回那些日子和它们之间的每一天的行。现在只需加入您的表...我没有尝试过,因为我没有您的数据库结构,但类似以下的东西应该可以工作:

SET @date_min = '2016-03-04';
SET @date_max = '2016-03-10';

SELECT
   date_generator.date,
   ifnull(SUM(val1),0) as sum_val
from (
   select DATE_ADD(@date_min, INTERVAL (@i:=@i+1)-1 DAY) as `date`
   from information_schema.columns,(SELECT @i:=0) gen_sub 
   where DATE_ADD(@date_min,INTERVAL @i DAY) BETWEEN @date_min AND @date_max
) date_generator
left join table1 on table1.date = date_generator.date
GROUP BY date;

【讨论】:

    【解决方案3】:

    使用下面的代码,它与您的查询类似,肯定对您有用且对您有帮助。

    $query = "SELECT date, SUM(val1) as sum_val  
    FROM table1  
    WHERE date BETWEEN '2016-03-04' AND '2016-03-10'  
    GROUP BY date";
    $result = mysql_db_query($db,$query);
    $dateArray = Array();
    foreach($result as $row)
    {
        $dateArray[] = strtotime($row['date']);
    }
    
    
    $from = "1-4-2016";
    $to = "30-4-2016";
    $datediff = strtotime($from) - strtotime($to);
    $days = floor($datediff/(60*60*24));
    for ($d1 = 1; $d1<$days; $d1++) {
        $cdate = strtotime("+".$d1." day", strtotime($from));
        if(!in_array($cdate, $dateArray))
        {
            // Insert record with zero
        }
    }
    

    【讨论】:

    • 但为什么是 30 天?
    • 它是一个月,如果你想让它动态化,那么我们需要找到从和到日期之间的总天数,然后将它传递给 $d1
    • 是的,我需要它是动态的。
    • 请检查已编辑的答案,它肯定适合您。 @HerilMuratovic
    • 请提供您的反馈。 @HerilMuratovic
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-12
    • 1970-01-01
    • 2018-04-24
    • 2021-07-22
    • 2016-04-30
    • 2019-06-08
    相关资源
    最近更新 更多