检索并绘制一段时间内的数据

发布于 2024-11-15 15:22:10 字数 432 浏览 0 评论 0原文

我一次又一次地遇到这个问题;

情况 有一个(大)数据集,其中的记录与日期(甚至时间)相关,我需要随时间绘制这些数据。

问题 数据集仅包含有可用记录的日期(显然),但我还需要“空”日期才能随着时间的推移均匀地绘制多个系列。

工具 我通常使用 MySQL 和 PHP,最常将数据粘贴到 Excel 中以绘制图表等。

解决方法 到目前为止,我通常会创建一个 Excel 工作表并手动输入日期,并使用数据集上的 SumIf 确定适当的结果数量。 不过,这对我来说似乎有点愚蠢,并且在处理大量记录时并不真正可行(Excel 很快就会变得非常慢)。

我真的很好奇是否没有一个“真正的”更好的解决方案来做到这一点,也许已经在查询的构建中?

I run into this problem again and again;

Situation
there is a (large) dataset with records tied to a date (or even time) and I have the need to plot this data over time.

Problem
The dataset only contains the dates for which there are records available (obviously), but I need also the 'empty' dates to be able to plot multiple series evenly over time.

Tools
I usually work with MySQL and PHP, most often pasting the data into Excel to plot graphs etc.

Workaround
Up till this moment I usually create an excel sheet and put in the dates by hand and determine the appropriate number of results with a SumIf on the dataset.
This seems a bit stupid to me though, and isn't really workable when working with a lot of records (excel gets really REALLY slow quite quickly).

I'm really curious to see if there isn't a 'real' and better solution to do this, maybe already in the construction of the query?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

最美的太阳 2024-11-22 15:22:10

您的 Excel 数据文本中的日期是否看起来像日期,或者日期序列号是否格式化为显示为日期?

如果日期数据点是日期序列号,则绘图将随时间均匀地间隔 X 轴,而不管各个数据点之间的间隔如何

附图演示:第一列和绘图是存储为文本的“日期”,第二个日期序列号格式化为日期

Demo of Plot

Are dates in you excel data text that look like dates, or date serial numbers formatted to display as dates?

If the date data points are date serial numbers then the plot will space the X axis evenly over time irrespective of interval between individual data points

The attached image demontrates: the first column and plot are "Dates" stored as text, the second date serial numbers formatted as dates

Demo of Plot

帅气称霸 2024-11-22 15:22:10

一个明显的解决方案是创建一个包含该范围内每个日期的表,并选择与此相连的数据:

  CREATE TABLE days ( day DATE NOT NULL, PRIMARY KEY day );
  INSERT INTO days (day) VALUES (20110101);
  INSERT INTO days (day) VALUES (20110102);
  ....
  SELECT days.day, yourtable.*
  FROM days LEFT JOIN yourtable
     ON days.day=yourtable.day;

或者,您可以使用 PHP 注入缺失的日期(但我认为 jupaju 的代码相当有缺陷):

  // ensure your qry returns DATE_FORMAT(day, '%Y-%m-%d') AS day
  $lastday='';
  while ($r=mysql_fetch_assoc($qry_result)) {
      if (!$lastday) $lastday=$r['day'];
      while ($r['day']>$lastday) {
          print $lastday . "\n";
          $lastday=add_day($lastday);
      }
      unset($r['day']);
      print $lastday . ',' . implode(',', $r) . "\n";
  }

  function add_day($day)
  {
     list($yr, $mo, $da)=explode('-',$day);
     $t=mktime(4,0,0,$mo, $da, $yr)+24*60*60; // NB not all days are 24 hours
     return date('Y-m-d',$t);
  }

One obvious solution would be to create a table containing every date in the range and select your data left joined to this:

  CREATE TABLE days ( day DATE NOT NULL, PRIMARY KEY day );
  INSERT INTO days (day) VALUES (20110101);
  INSERT INTO days (day) VALUES (20110102);
  ....
  SELECT days.day, yourtable.*
  FROM days LEFT JOIN yourtable
     ON days.day=yourtable.day;

Alternatively you could inject the missing days using PHP (but I think jupaju's code is rather flawed):

  // ensure your qry returns DATE_FORMAT(day, '%Y-%m-%d') AS day
  $lastday='';
  while ($r=mysql_fetch_assoc($qry_result)) {
      if (!$lastday) $lastday=$r['day'];
      while ($r['day']>$lastday) {
          print $lastday . "\n";
          $lastday=add_day($lastday);
      }
      unset($r['day']);
      print $lastday . ',' . implode(',', $r) . "\n";
  }

  function add_day($day)
  {
     list($yr, $mo, $da)=explode('-',$day);
     $t=mktime(4,0,0,$mo, $da, $yr)+24*60*60; // NB not all days are 24 hours
     return date('Y-m-d',$t);
  }
﹏雨一样淡蓝的深情 2024-11-22 15:22:10

使用 PHP 我会做这样的事情(假设 db-results 位于 $res 中,日期为 Ymd 作为键):

$year = date('Y');
for ($month = 1; $month <= 12; $month++) {
    $last_day = date('t', mktime(0, 0, 0, 1, $month, $year));
    for ($day = 1; $day <= $last_day; $day++) {
        $key = sprintf('%4d-%02d-%02d', $year, $month, $day);
        if (!empty($res[$key])) {
            $output[$key] = $res[$key];
        } else {
            $output[$key] = 0;
        }
    }
}

这样你会得到一个数组 $output 具有值为 0 的空日期。

Using PHP I would do something like this (assuming db-results are in $res having date as Y-m-d as key):

$year = date('Y');
for ($month = 1; $month <= 12; $month++) {
    $last_day = date('t', mktime(0, 0, 0, 1, $month, $year));
    for ($day = 1; $day <= $last_day; $day++) {
        $key = sprintf('%4d-%02d-%02d', $year, $month, $day);
        if (!empty($res[$key])) {
            $output[$key] = $res[$key];
        } else {
            $output[$key] = 0;
        }
    }
}

That way you'll get an array $output with empty dates having value 0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文