【问题标题】:PHP Mysql group by date from accumulative valuesPHP Mysql按日期从累积值分组
【发布时间】:2011-01-21 15:23:43
【问题描述】:

我有一个带有 ID、value1、value2、value3 和 tstamp(TIMESTAMP 格式)的表,我试图按每天分组并找到每天的总数,但是所有值都是累积的,这会造成问题,因为 sum(value1) 没有给出正确的输出,这是我的代码:

$sql = "select date(tstamp), sum(".$column.") from mash group by date(tstamp) order by tstamp asc limit 10";
$result = mysql_query($sql);
$previous = 0;
$firstRun = true;
while($row = mysql_fetch_array($result))
{
  $difference = $row[1] - $previous;
  if (!$firstRun)
  {
     $strXML .= "<set name='".$row[0]."' value='".$difference."' color='AFD8F8' />";
   }
  $previous = $row[1];
  $firstRun = false;
}

任何人都可以在这段代码中发现问题,它没有出错,只是给出了错误的答案。

编辑:

为了消除任何混淆,这是 SQL:

 --------------------------------------------------------

--
-- Table structure for table `mash`
--

CREATE TABLE IF NOT EXISTS `mash` (
  `id` int(25) NOT NULL AUTO_INCREMENT,
  `steam` int(25) NOT NULL,
  `bore_water` int(25) NOT NULL,
  `boiler1oil` int(25) NOT NULL,
  `boiler2oil` int(25) NOT NULL,
  `tstamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5362 ;

--
-- Dumping data for table `mash`
--

INSERT INTO `mash` (`id`, `steam`, `bore_water`, `boiler1oil`, `boiler2oil`, `tstamp`) VALUES
(2, 436, 73, 15, 1, '2010-11-25 12:28:03'),
(3, 495, 74, 36, 1, '2010-11-25 12:38:04'),
(4, 553, 76, 58, 1, '2010-11-25 12:48:09'),
(5, 565, 77, 74, 1, '2010-11-25 12:58:05'),
(6, 584, 79, 78, 1, '2010-11-25 13:08:05'),
(7, 630, 82, 100, 1, '2010-11-25 13:18:11'),
(8, 686, 86, 130, 1, '2010-11-25 13:28:07'),
(9, 740, 89, 151, 1, '2010-11-25 13:38:07'),
(10, 780, 93, 173, 1, '2010-11-25 13:48:13'),
(11, 883, 100, 218, 1, '2010-11-25 14:08:10');

【问题讨论】:

  • 您不能按DATE(tstamp) 分组,然后按最后一个具有您要查找的值的条目排序吗?
  • 我不知道为什么它不起作用布拉德,但在某些方面它给出了负结果,这绝对是不正确的。我试过 desc 和 asc 都不管用
  • @benhowdle89:我现在正在填充一个演示数据库,所以我有一些东西要测试。假设您希望每天从最新(最后插入的)条目中获得“value1”、“value2”等(因为最后一个始终是前一个值加上新值?)
  • 嗨布拉德,感谢您抽出宝贵时间回答这个问题,请参阅我编辑的答案:)
  • @benhowdle 现在看过了,我相信您正在寻找每列的 MAX(),按 DATE(tstamp) 分组。例如SELECT DATE(tstamp), MAX(Steam) As Max_Steam FROM mash GROUP BY DATE(tstamp);

标签: php mysql math


【解决方案1】:

假设我正确阅读了您的表格,您正在寻找“value1”(或 value2 等)的最后一个条目,它实际上是总和(根据您提到的累积值来判断)

+----+------+---------------------+
| id | val  | tstamp              |
+----+------+---------------------+
|  6 |    1 | 2010-01-02 01:00:00 |
|  7 |    4 | 2010-01-02 02:00:00 |
|  8 |    6 | 2010-01-02 03:00:00 |
|  9 |   15 | 2010-01-02 04:00:00 |
| 10 |   20 | 2010-01-02 05:00:00 | <-- this value
| 11 |    1 | 2010-01-03 01:00:00 |
| 12 |    4 | 2010-01-03 02:00:00 |
| 13 |    6 | 2010-01-03 03:00:00 |
| 14 |   15 | 2010-01-03 04:00:00 |
| 15 |   20 | 2010-01-03 05:00:00 | <- this value
|  1 |    2 | 2010-02-01 01:00:00 |
|  2 |    8 | 2010-02-01 02:00:00 |
|  3 |   16 | 2010-02-01 03:00:00 |
|  4 |   32 | 2010-02-01 04:00:00 |
|  5 |   64 | 2010-02-01 05:00:00 | <- this value
+----+------+---------------------+

那么你应该可以使用MAX&DATE了:

SELECT    DATE(tstamp), MAX(val)
FROM      mash
GROUP     DATE(tstamp)
ORDER BY  tstamp ASC;

这将产生:

+--------------+----------+
| DATE(tstamp) | MAX(val) |
+--------------+----------+
| 2010-01-02   |       20 |
| 2010-01-03   |       20 |
| 2010-02-01   |       64 |
+--------------+----------+

【讨论】:

  • 嗨布拉德,我知道你已经给了我一个完整的答案,但我有一个想法。因为每个值总是大于它之前的值(它也永远不会重置)。我看到的问题是说第 1 天的最大值是 3456(因此那天的总数)以及第 2 天将从 3456 开始并且只会增加。因此,我绘制的图表不断增加,因为每个总数也是从前一天添加的!那有意义吗?有什么办法吗?
【解决方案2】:

如果您按日期分组,它将按日期的最小增量进行分组。您应该按日期分组。比如:

select DATE_FORMAT(tstamp, '%Y-%m-%c') as ymd, sum(".$column.") from mash group by ymd order by tstamp asc limit 10

这将为您提供分组依据的年-月-日格式。如果您需要单独访问年月日值,请执行以下操作:

select YEAR(tstamp) as year, MONTH(tstamp) as month, DAY(tstamp) as day, sum(".$column.") from mash group by year, month, day order by tstamp asc limit 10

【讨论】:

  • 仅供参考,DATE() 函数执行的结果与您的 DATE_FORMAT 相同。
  • 嗯,谢谢 Photon,这如何适合我上面的代码?
  • 基本上是替换SQL查询本身。对不起,我错过了你描述的累积部分,我看到你有一个有效的答案。 :)
【解决方案3】:

您问题的关键部分不是GROUP BY 部分,它可以正常工作,这就是您所说的累积。

如果您的意思是某列跟踪一年中每一天的总降雨量(即,由于两个记录之间的增量是当天发生的实际降雨量,所以数字一直在上升)那么您需要什么要做的是首先摆脱三角洲。不管你怎么做,SQL 都会有点麻烦,所以你最好用 PHP 来做,但这里是我尝试使用 SQL。

create temporary table foo select * from bar;

create temporary table non_accumulative
select b.id, b.rain - f.rain as "rain", rain_timestamp from bar b join foo f on (f.id + 1) = b.id;

select sum(rain), date(rain_timestamp) from non_accumulative group by date(rain_timestamp) order by rain_timestamp;

当然,您可以对子选择执行相同的操作,但我发现临时表更快。

【讨论】:

    猜你喜欢
    • 2014-04-12
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多