PHP/MySQL 无法弄清楚如何根据我当前的表格对数据进行分组和打印

PHP/MySQL Cant figure out how to group and print data based on my current tables

我有这个 table,还有一些样本数据。

CREATE TABLE IF NOT EXISTS ooscount (
   id int(10) NOT NULL AUTO_INCREMENT,
   agcid int(3) NOT NULL,
   ooscount int(10) NOT NULL,
   `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (id)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=246045 ;

--
-- Dumping data for table 'ooscount'
--

INSERT INTO `ooscount` (`id`, `agcid`, `ooscount`, `date`) VALUES
(209855, 4, 2869, '2018-03-01 18:00:02'),
(209856, 2, 3183, '2018-03-01 18:00:02'),
(209857, 1, 4906, '2018-03-01 18:00:02'),
(209860, 3, 5596, '2018-03-01 18:00:02'),
(209863, 14, 6019, '2018-03-01 18:00:02'),
(209864, 16, 7564, '2018-03-01 18:00:02'),
(209873, 4, 2870, '2018-03-01 18:05:01'),
(209874, 2, 3182, '2018-03-01 18:05:01'),
(209876, 1, 4899, '2018-03-01 18:05:01'),
(209877, 3, 5598, '2018-03-01 18:05:01'),
(209879, 14, 6018, '2018-03-01 18:05:01'),
(209882, 16, 7557, '2018-03-01 18:05:01');

我正在为现有数据和新数据设置一个不同的 charting/graphing 系统,希望我不需要将存储方法更改为 MySQL。

我想要的结果是这样的: 第一个数字是 agcid,第二个数字是 ooscount。我每 5 分钟对该数据进行一次采样,并希望它以 5 分钟的间隔绘制过去 7 小时的数据图表。

    "dataProvider": [
                        {
    "1": 2055,
    "2": 3845,
    "3": 4455,
    "4": 5051,
    "14": 9012,
    "16": 6522,
    "date": "2018-03-08 02:45"
},
{
    "1": 2077,
    "2": 3841,
    "3": 4450,
    "4": 5055,
    "14": 9033,
    "16": 6524,
    "date": "2018-03-08 02:50"
},
{
    "1": 2076,
    "2": 3821,
    "3": 4452,
    "4": 5057,
    "14": 9064,
    "16": 6525,
    "date": "2018-03-08 02:55"
},
{
    "1": 2071,
    "2": 3814,
    "3": 4460,
    "4": 5059,
    "14": 9011,
    "16": 6521,
    "date": "2018-03-08 03:00"
},
{
    "1": 2064,
    "2": 3832,
    "3": 4490,
    "4": 5052,
    "14": 9013,
    "16": 6496,
    "date": "2018-03-08 03:05"
},

虽然我想不出实现此目标的最佳方法。

根据上面的 tables,数据将是 agcid:查询中每个 agcid 的 ooscount(当前为 6)

SELECT agcid, ooscount, DATE
FROM ooscount
WHERE agcid
IN ( 1, 2, 3, 4, 14, 16 ) 
AND DATE >= DATE_SUB( NOW( ) , INTERVAL 7 HOUR ) 
ORDER BY DATE
LIMIT 0 , 30

使用 AmCharts,目标是在一张图表上绘制这 6 个数据点。

一种方法是在 fetch_row 循环期间对 PHP 中的行进行分组,例如(为简洁起见省略了错误检查):

$db = new mysqli('server', 'user', 'pass','db');
$result = $db->query("SELECT agcid, ooscount, `date` FROM ooscount WHERE agcid IN ( 1, 2, 3, 4, 14, 16 ) AND DATE >= DATE_SUB( NOW( ) , INTERVAL 7 HOUR )  ORDER BY DATE LIMIT 0 , 30");

$res = [];

$current_row = [];
while ($row = $result->fetch_assoc()) {
        if (!isset($current_row['date']))  {
                $current_row['date'] = $row['date'];
        }
        else if ($current_row['date'] != $row['date']) {
                $res[] = $current_row;
                $current_row = ['date'=>$row['date']];
        }

        $current_row[$row['agcid']] = $row['ooscount'];
}
$res[] = $current_row;

echo json_encode($res);

另一种方法是旋转结果集,使每个 id 都是一列,并使用 this answer 中的技术按日期对其进行分组。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(distinct
    CONCAT(
      'sum(case when agcid = ',
      agcid,
      ' then ooscount else 0 end) AS ''',
      replace(agcid, ' ', ''),
      ''''
    )
  ) INTO @sql
from (select distinct agcid from ooscount) a;

SET @sql = CONCAT('SELECT `date`, ', @sql, ' from ooscount where `date` >= DATE_SUB( NOW( ) , INTERVAL 7 HOUR ) group by `date`');
PREPARE stmt from @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

在这种情况下,我使用动态版本来提取所有 ID,但如果您只需要特定 ID,您可以相应地调整它。使用您提供的转储,这将为您提供以下结果集:

+---------------------+------+------+------+------+------+------+
| date                | 4    | 2    | 1    | 3    | 14   | 16   |
+---------------------+------+------+------+------+------+------+
| 2018-03-01 18:00:02 | 2869 | 3183 | 4906 | 5596 | 6019 | 7564 |
| 2018-03-01 18:05:01 | 2870 | 3182 | 4899 | 5598 | 6018 | 7557 |
+---------------------+------+------+------+------+------+------+

您可以在脚本中使用 mysqli::multi_query 将所有内容组合在一起,如下所示:

$sql = <<<SQL
SET @sql = NULL;
SELECT
  GROUP_CONCAT(distinct
    CONCAT(
      'sum(case when agcid = ',
      agcid,
      ' then ooscount else 0 end) AS ''',
      replace(agcid, ' ', ''),
      ''''
    )
  ) INTO @sql
from (select distinct agcid from ooscount) a;

SET @sql = CONCAT('SELECT `date`, ', @sql, ' from ooscount where `date` >= DATE_SUB( NOW( ) , INTERVAL 7 HOUR ) group by `date`');
PREPARE stmt from @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SQL;

$db->multi_query($sql);

do {
        if ($result = $db->store_result()) {
                $results = [];
                while ($row = $result->fetch_assoc()) {
                        $results[] = $row;
                }
        }
} while ($db->more_results() && $db->next_result());

echo json_encode($results);

这两种方法都会为您提供所需的 dataProvider 布局:

[{
    "date": "2018-03-01 18:00:02",
    "4": "2869",
    "2": "3183",
    "1": "4906",
    "3": "5596",
    "14": "6019",
    "16": "7564"
}, {
    "date": "2018-03-01 18:05:01",
    "4": "2870",
    "2": "3182",
    "1": "4899",
    "3": "5598",
    "14": "6018",
    "16": "7557"
}]