【问题标题】:Querying MySQL Table to Return JSON查询 MySQL 表以返回 JSON
【发布时间】:2018-04-02 14:30:26
【问题描述】:

我有一个带有温度传感器数据的 MySQL 表,我正在尝试将它的数据放入 JSON 数组中,以便输出到带有 JavaScript 图表的 PHP 页面。

这是我的表格和一些示例数据:

+----+----------+---------------------+-------+
| id | sensorId |    dateRecorded     | tempF |
+----+----------+---------------------+-------+
|  1 |        1 | 2018-03-31 10:00:00 |  34.2 |
|  2 |        2 | 2018-03-31 10:00:00 |  83.1 |
|  3 |        2 | 2018-03-31 10:05:00 |  44.5 |
|  4 |        1 | 2018-03-31 10:05:00 |  65.2 |
+----+----------+---------------------+-------+


我想要作为输出的 JSON 结构是这样的:

data: [
    { dateRecorded: '2018-03-31 10:00:00', sensor1: 34.2, sensor2: 83.1 },
    { dateRecorded: '2018-03-31 10:05:00', sensor1: 65.2, sensor2: 44.5 }
]


我可以单独返回每个传感器数据,但我似乎无法弄清楚如何按 dateRecorded 列对输出进行分组,然后将每个传感器的数据放在它自己的键/值对中的一行上?

【问题讨论】:

  • 你有多少个传感器??
  • 该输出 JSON 结构不是有效的 JSON。 -> 试试jsonlint.com

标签: php mysql json


【解决方案1】:

您的 JSON 输出结构不是有效的 JSON。

data: [
    { dateRecorded: '2018-03-31 10:00:00', sensor1: 34.2, sensor2: 83.1 },
    { dateRecorded: '2018-03-31 10:05:00', sensor1: 65.2, sensor2: 44.5 }
]

这是一个有效的 JSON 结构,所以这就是我在回答中的目标。

{
    "data": [{
        "dateRecorded": "2018-03-31 10:00:00",
        "sensor1": 34.2,
        "sensor2": 83.1
    }, {
        "dateRecorded": "2018-03-31 10:05:00",
        "sensor1": 65.2,
        "sensor2": 44.5
    }]
}

这仅适用于纯 MySQL。

创建表/插入数据

CREATE TABLE Table1
    (`id` int, `sensorId` int, `dateRecorded`datetime, `tempF` double)
;

INSERT INTO Table1
    (`id`, `sensorId`, `dateRecorded`, `tempF`)
VALUES
    (1, 1, '2018-03-31 10:00:00', 34.2),
    (2, 2, '2018-03-31 10:00:00', 83.1),
    (3, 2, '2018-03-31 10:05:00', 44.5),
    (4, 1, '2018-03-31 10:05:00', 65.2)
;

用 MySQL 之类的生成内部 JSON 结构

{
        "dateRecorded": "2018-03-31 10:00:00",
        "sensor1": 34.2,
        "sensor2": 83.1
    }, {
        "dateRecorded": "2018-03-31 10:05:00",
        "sensor1": 65.2,
        "sensor2": 44.5
    }

您需要使用函数 CONCAT 和 GROUP_CONCAT 来生成 JSON 字符串。

查询

SELECT 
   CONCAT (
       '{'
     , '"dateRecorded": ', '"', Table1.dateRecorded, '"'
     , ','
     , GROUP_CONCAT(     
         CONCAT(
           '"sensor', Table1.sensorId, '":', Table1.tempF
         )
         ORDER BY
          Table1.id ASC
       )
     , '}'
   )
    AS json_data_records
FROM 
 Table1 
GROUP BY
 Table1.dateRecorded
ORDER BY 
 Table1.dateRecorded ASC

结果

|                                                     json_data_records |
|-----------------------------------------------------------------------|
| {"dateRecorded": "2018-03-31 10:00:00","sensor1":34.2,"sensor2":83.1} |
| {"dateRecorded": "2018-03-31 10:05:00","sensor2":44.5,"sensor1":65.2} |

查看演示http://www.sqlfiddle.com/#!9/d6db452/6

p.s第二条记录中sensor1和sensor2的顺序颠倒了。
因为在 GROUP_CONCAT 函数中关闭 ORDER BY id ASC。
在源数据中存在此顺序。

像生成完整的JSON一样

{
    "data": [{
        "dateRecorded": "2018-03-31 10:00:00",
        "sensor1": 34.2,
        "sensor2": 83.1
    }, {
        "dateRecorded": "2018-03-31 10:05:00",
        "sensor1": 65.2,
        "sensor2": 44.5
    }]
}

我们需要更改现有查询,以便它使用 CONCAT 和 GROUP_CONCAT 来合并最后一个输出。

查询

SELECT 
 CONCAT(
    '{'
      , '"data": ['
          , GROUP_CONCAT(json_records.json)
     , ']'
   , '}'
 )
  AS json
FROM ( 
  SELECT
     CONCAT (
         '{'
       , '"dateRecorded": ', '"', Table1.dateRecorded, '"'
       , ','
       , GROUP_CONCAT(     
           CONCAT(
             '"sensor', Table1.sensorId, '":', Table1.tempF
           )
           ORDER BY
            Table1.id ASC
         )
       , '}'
     ) 
      AS json
  FROM 
   Table1 
  GROUP BY
   Table1.dateRecorded
  ORDER BY 
   Table1.dateRecorded ASC
) 
 AS json_records

结果

|                                                                                                                                                    json |
|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| {"data": [{"dateRecorded": "2018-03-31 10:00:00","sensor1":34.2,"sensor2":83.1},{"dateRecorded": "2018-03-31 10:05:00","sensor2":44.5,"sensor1":65.2}]} |

见演示http://www.sqlfiddle.com/#!9/d6db452/19

【讨论】:

  • 很抱歉我的原始帖子显示不正确的 JSON 结构,这是我第一次尝试使用 JSON。您的答案正是我想要的,我很欣赏深入解释每个部分的深度。
  • 所以我有一个后续问题。最初,当我的 sql 仅用于一个特定的传感器时,我使用这条线发送到 Morris JS 折线图<?php echo json_encode($rows);?> 这将输出如下内容:[{"dateRecorded":"2018-04-02 00:50:13","sensor1":"67.33"},{"dateRecorded":"2018-04-02 01:00:15","sensor1":"67.33"}] 但您的答案似乎是它已经有返回 JSON格式化后,它以对象数组的形式返回?然后我将如何输出折线图使用的结果?
  • @jclifford90 我不知道 Morris Javascript 折线图,所以你需要用 javascript 标签提出一个新问题。
猜你喜欢
  • 2018-10-09
  • 2016-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多