从MySQL中选择数据以获得多线图

时间:2017-12-06 18:57:30

标签: php mysql

我现在挣扎了一段时间,将数据构建到Google Chart可以接受的模型中。

图表需要这样的数据(json):

[
['Time',               'url1', 'url2', 'url3'   ],
['2017-12-06T12:00:00', 1,      2,       4      ],
['2017-12-06T13:00:00', 3,      6,       5      ],
['2017-12-06T14:00:00', 2,      5,       2      ],
['2017-12-06T15:00:00', 7,      3,       1      ],
]

所以它应该以类似的方式提取。有3个选项 - 用PHP / JS构建所有数据,或者用MySQL选择它,然后只清理。

MySQL数据库表' ping_history'看起来像这样:

|--------|-----------|-------------|---------------------|
| ID     | url       | ping        | created_at          |
|--------|-----------|-------------|---------------------|
| 0      | url1      | 1           | 2017-12-06T12:00:00 |
|--------|-----------|-------------|---------------------|
| 1      | url2      | 2           | 2017-12-06T12:00:00 |
|--------|-----------|-------------|---------------------|
| 2      | url3      | 4           | 2017-12-06T12:00:10 |
|--------|-----------|-------------|---------------------|
| 3      | url1      | 3           | 2017-12-06T13:00:20 |
|--------|-----------|-------------|---------------------|
| 4      | url2      | 6           | 2017-12-06T13:00:30 |
|--------|-----------|-------------|---------------------|
| 5      | url3      | 5           | 2017-12-06T13:00:00 |
|--------|-----------|-------------|---------------------|
| 6      | url1      | 2           | 2017-12-06T14:00:40 |
|--------|-----------|-------------|---------------------|
| 7      | url2      | 5           | 2017-12-06T14:00:00 |
|--------|-----------|-------------|---------------------|
| 8      | url3      | 2           | 2017-12-06T14:00:00 |
|--------|-----------|-------------|---------------------|
| 9      | url1      | 7           | 2017-12-06T15:00:01 |
|--------|-----------|-------------|---------------------|
| 10     | url2      | 3           | 2017-12-06T15:00:02 |
|--------|-----------|-------------|---------------------|
| 11     | url3      | 1           | 2017-12-06T15:00:03 |
|--------|-----------|-------------|---------------------|

记录按HOUR(created_at)分组,ping选为MAX(ping)。

如何使这些分组的网址行显示为列标题或第一行,特定网址的所有记录都显示为垂直...如果没有日期值 - 我们使用null。

也许我只是不知道这种方法是如何被调用的,并且不能谷歌它。像旋转结果集的东西:)请帮忙!

2 个答案:

答案 0 :(得分:0)

尝试以下

SELECT
    DATE_FORMAT(created_at, "%Y-%m-%dT%H:00:00") `Time`,
    MAX(CASE WHEN url='url1' THEN ping END) `url1`,
    MAX(CASE WHEN url='url2' THEN ping END) `url2`,
    MAX(CASE WHEN url='url3' THEN ping END) `url3`
FROM ping_history
GROUP BY DATE_FORMAT(created_at, "%Y-%m-%dT%H:00:00")

答案 1 :(得分:0)

感谢@ ravinder-reddy,我被引导到正确的方向并设法构建我需要的东西。 @ leran2002答案很好,当你有已知的项目数组。在我的情况下,它是未知的,因此必须进行动态选择。我最终得到了一个存储过程。这是:

CREATE DEFINER=`%`@`%` PROCEDURE `get_chart_history_pings`(IN masterId INT, IN daysLimit INT)
BEGIN
    SET SESSION group_concat_max_len = 1000000;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'ifnull(MAX(case when url = ''',
          url,
          ''' then ping end), null) AS `',
          url, '`'
        )
      ) INTO @sql
    FROM
      history
    WHERE 
      url IN (
        SELECT url FROM hosts WHERE id = masterId
      )
      OR url = ( SELECT url FROM masters WHERE id = masterId LIMIT 1 );

    SET @sql = CONCAT('SELECT date_format(created_at, "%Y%-%m%-%d% %H%:%i%:00" ) as time, ', @sql, ' 
                      FROM history
                      WHERE created_at > DATE_SUB(now(), INTERVAL ',daysLimit,' DAY)
                      GROUP BY date_format( created_at, "%Y%m%d%H" )
                      ORDER BY created_at ASC');

    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END

同样归功于@mihai,因为他的回答https://stackoverflow.com/a/28284999/2470912导致了这个解决方案。