Php 如何在特定结果布局中组合具有不同行数的表

Php 如何在特定结果布局中组合具有不同行数的表,php,mysql,Php,Mysql,我搜索了互联网和这个论坛,但没有找到正确的答案。我正在尝试连接不同的表(位置、传感器、SensorRawData)并寻找特定的输出 我试着将组_CONCAT与JOIN ect相结合。但是没有人给我我想要的结果 为了显示表和示例查询,我创建了一个SQL FIDLE: 仅使用连接是不可能的,但是使用组连接或联合并不能提供我想要的解决方案 SELECT Location, SensorName, TrafficShaper, TrafficIN, TrafficOut, Outage FROM Loc

我搜索了互联网和这个论坛,但没有找到正确的答案。我正在尝试连接不同的表(位置、传感器、SensorRawData)并寻找特定的输出

我试着将组_CONCAT与JOIN ect相结合。但是没有人给我我想要的结果

为了显示表和示例查询,我创建了一个SQL FIDLE:

仅使用连接是不可能的,但是使用组连接或联合并不能提供我想要的解决方案

SELECT Location, SensorName, TrafficShaper, TrafficIN, TrafficOut, Outage
FROM Locations
JOIN Sensors ON Sensors.LocationsID = Locations.ID
JOIN SensorRawData ON SensorRawData.SensorID = Sensors.SensorID
WHERE SensorRawData.TimeStamp BETWEEN '2019-03-13 00:00:00' AND '2019-03-13 23:59:59'
ORDER BY Location, Sensors.Queue
我正在寻找的输出应该是这样的(对不起,现在还不能使用图片,所以它是一个url)

因此,首先水平对齐位置,然后按位置和队列的顺序对齐五个队列(按位置排序,Sensors.Queue)。在队列中,我需要所选日期时间之间的最高TrafficIN和最高TrafficOut值


如何操作?

假设样本数据中的传感器队列不超过5个,则可以使用条件聚合来获得所需的结果:

SELECT Location,
       MAX(CASE WHEN SensorName = 'Queue 1' THEN TrafficIN END) AS `Queue 1 IN`,
       MAX(CASE WHEN SensorName = 'Queue 1' THEN TrafficOut END) AS `Queue 1 Out`,
       MAX(CASE WHEN SensorName = 'Queue 2' THEN TrafficIN END) AS `Queue 2 IN`,
       MAX(CASE WHEN SensorName = 'Queue 2' THEN TrafficOut END) AS `Queue 2 Out`,
       MAX(CASE WHEN SensorName = 'Queue 3' THEN TrafficIN END) AS `Queue 3 IN`,
       MAX(CASE WHEN SensorName = 'Queue 3' THEN TrafficOut END) AS `Queue 3 Out`,
       MAX(CASE WHEN SensorName = 'Queue 4' THEN TrafficIN END) AS `Queue 4 IN`,
       MAX(CASE WHEN SensorName = 'Queue 4' THEN TrafficOut END) AS `Queue 4 Out`,
       MAX(CASE WHEN SensorName = 'Queue 5' THEN TrafficIN END) AS `Queue 5 IN`,
       MAX(CASE WHEN SensorName = 'Queue 5' THEN TrafficOut END) AS `Queue 5 Out`
FROM Locations l
LEFT JOIN Sensors s ON s.LocationsID = l.ID
LEFT JOIN SensorRawData r ON r.SensorID = s.SensorID
                         AND r.TimeStamp BETWEEN '2019-03-13 00:00:00' AND '2019-03-13 23:59:59'
GROUP BY Location
输出是图像中显示的原始数据;更改应用程序中的显示格式可能是最容易的


我已更新您的以显示结果。

假设示例数据中的传感器队列不超过5个,您可以使用条件聚合来获得所需的结果:

SELECT Location,
       MAX(CASE WHEN SensorName = 'Queue 1' THEN TrafficIN END) AS `Queue 1 IN`,
       MAX(CASE WHEN SensorName = 'Queue 1' THEN TrafficOut END) AS `Queue 1 Out`,
       MAX(CASE WHEN SensorName = 'Queue 2' THEN TrafficIN END) AS `Queue 2 IN`,
       MAX(CASE WHEN SensorName = 'Queue 2' THEN TrafficOut END) AS `Queue 2 Out`,
       MAX(CASE WHEN SensorName = 'Queue 3' THEN TrafficIN END) AS `Queue 3 IN`,
       MAX(CASE WHEN SensorName = 'Queue 3' THEN TrafficOut END) AS `Queue 3 Out`,
       MAX(CASE WHEN SensorName = 'Queue 4' THEN TrafficIN END) AS `Queue 4 IN`,
       MAX(CASE WHEN SensorName = 'Queue 4' THEN TrafficOut END) AS `Queue 4 Out`,
       MAX(CASE WHEN SensorName = 'Queue 5' THEN TrafficIN END) AS `Queue 5 IN`,
       MAX(CASE WHEN SensorName = 'Queue 5' THEN TrafficOut END) AS `Queue 5 Out`
FROM Locations l
LEFT JOIN Sensors s ON s.LocationsID = l.ID
LEFT JOIN SensorRawData r ON r.SensorID = s.SensorID
                         AND r.TimeStamp BETWEEN '2019-03-13 00:00:00' AND '2019-03-13 23:59:59'
GROUP BY Location
输出是图像中显示的原始数据;更改应用程序中的显示格式可能是最容易的


我已经更新了您的以显示结果。

这里是使用交叉表查询获取数据的另一种方法:

SELECT `Location`,
CONCAT("Queue 1 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 1', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 1', `TrafficOUT`, 0)),")") AS `Queue 1`,
CONCAT("Queue 2 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 2', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 2', `TrafficOUT`, 0)),")") AS `Queue 2`,
CONCAT("Queue 3 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 3', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 3', `TrafficOUT`, 0)),")") AS `Queue 3`,
CONCAT("Queue 4 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 4', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 4', `TrafficOUT`, 0)),")") AS `Queue 4`,
CONCAT("Queue 5 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 5', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 5', `TrafficOUT`, 0)),")") AS `Queue 5`
FROM `Locations` 
JOIN `Sensors` ON `Sensors`.`LocationsID` = `Locations`.`ID`
JOIN `SensorRawData` ON `SensorRawData`.`SensorID` = `Sensors`.`SensorID`
WHERE `SensorRawData`.`TimeStamp` BETWEEN '2019-03-13 00:00:00' AND '2019-03-13 23:59:59'
-- ORDER BY `Locations`.`Location`, `Sensors`.`Queue`
GROUP BY `Locations`.`Location`           
这将产生以下输出:

| Location | Queue 1                              | Queue 2                              | Queue 3                              | Queue 4                              | Queue 5                               |
| -------- | ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------- |
| Voorburg | Queue 1 (IN:1.475493 / OUT:1.977284) | Queue 2 (IN:0.272115 / OUT:0.266318) | Queue 3 (IN:0.057073 / OUT:0.044036) | Queue 4 (IN:0.174479 / OUT:7.849057) | Queue 5 (IN:10.067641 / OUT:3.057053) |
使用交叉表可能有点复杂,但它确实允许您在MySQL中透视表,同时允许您选择使用更复杂的表达式以所需的格式获得结果。例如,我使用
CONCAT()。使用以下示例,您应该能够使用第一个答案完成此操作:

CONCAT("Queue 1 (IN:", MAX(CASE WHEN SensorName = 'Queue 1' THEN TrafficIN END), " / OUT:",MAX(CASE WHEN SensorName = 'Queue 1' THEN TrafficOut END),")") AS "",
就像我说的,这只是获取数据的另一种方式

更新:在看到关于流量整形器的评论后,我将其添加到查询中,以便于:

SELECT `Location`,
CONCAT("Queue 1 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 1', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 1', `TrafficOUT`, 0)),") Shaper:", (SELECT `Sensors`.`TrafficShaper` FROM `Sensors` WHERE `Sensors`.`SensorName` = 'Queue 1')) AS `Queue 1`,
CONCAT("Queue 2 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 2', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 2', `TrafficOUT`, 0)),") Shaper:", (SELECT `Sensors`.`TrafficShaper` FROM `Sensors` WHERE `Sensors`.`SensorName` = 'Queue 2')) AS `Queue 2`,
CONCAT("Queue 3 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 3', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 3', `TrafficOUT`, 0)),") Shaper:", (SELECT `Sensors`.`TrafficShaper` FROM `Sensors` WHERE `Sensors`.`SensorName` = 'Queue 3')) AS `Queue 3`,
CONCAT("Queue 4 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 4', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 4', `TrafficOUT`, 0)),") Shaper:", (SELECT `Sensors`.`TrafficShaper` FROM `Sensors` WHERE `Sensors`.`SensorName` = 'Queue 4')) AS `Queue 4`,
CONCAT("Queue 5 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 5', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 5', `TrafficOUT`, 0)),") Shaper:", (SELECT `Sensors`.`TrafficShaper` FROM `Sensors` WHERE `Sensors`.`SensorName` = 'Queue 5')) AS `Queue 5`
FROM `Locations` 
JOIN `Sensors` ON `Sensors`.`LocationsID` = `Locations`.`ID`
JOIN `SensorRawData` ON `SensorRawData`.`SensorID` = `Sensors`.`SensorID`
WHERE `SensorRawData`.`TimeStamp` BETWEEN '2019-03-13 00:00:00' AND '2019-03-13 23:59:59'
-- ORDER BY `Locations`.`Location`, `Sensors`.`Queue`
GROUP BY `Locations`.`Location`
这将产生以下输出:

| Location | Queue 1                                          | Queue 2                                          | Queue 3                                          | Queue 4                                          | Queue 5                                           |
| -------- | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------- |
| Voorburg | Queue 1 (IN:1.475493 / OUT:1.977284) Shaper:2048 | Queue 2 (IN:0.272115 / OUT:0.266318) Shaper:8192 | Queue 3 (IN:0.057073 / OUT:0.044036) Shaper:5120 | Queue 4 (IN:0.174479 / OUT:7.849057) Shaper:2048 | Queue 5 (IN:10.067641 / OUT:3.057053) Shaper:3072 |

下面是另一种使用交叉表查询获取数据的方法:

SELECT `Location`,
CONCAT("Queue 1 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 1', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 1', `TrafficOUT`, 0)),")") AS `Queue 1`,
CONCAT("Queue 2 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 2', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 2', `TrafficOUT`, 0)),")") AS `Queue 2`,
CONCAT("Queue 3 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 3', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 3', `TrafficOUT`, 0)),")") AS `Queue 3`,
CONCAT("Queue 4 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 4', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 4', `TrafficOUT`, 0)),")") AS `Queue 4`,
CONCAT("Queue 5 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 5', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 5', `TrafficOUT`, 0)),")") AS `Queue 5`
FROM `Locations` 
JOIN `Sensors` ON `Sensors`.`LocationsID` = `Locations`.`ID`
JOIN `SensorRawData` ON `SensorRawData`.`SensorID` = `Sensors`.`SensorID`
WHERE `SensorRawData`.`TimeStamp` BETWEEN '2019-03-13 00:00:00' AND '2019-03-13 23:59:59'
-- ORDER BY `Locations`.`Location`, `Sensors`.`Queue`
GROUP BY `Locations`.`Location`           
这将产生以下输出:

| Location | Queue 1                              | Queue 2                              | Queue 3                              | Queue 4                              | Queue 5                               |
| -------- | ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------- |
| Voorburg | Queue 1 (IN:1.475493 / OUT:1.977284) | Queue 2 (IN:0.272115 / OUT:0.266318) | Queue 3 (IN:0.057073 / OUT:0.044036) | Queue 4 (IN:0.174479 / OUT:7.849057) | Queue 5 (IN:10.067641 / OUT:3.057053) |
使用交叉表可能有点复杂,但它确实允许您在MySQL中透视表,同时允许您选择使用更复杂的表达式以所需的格式获得结果。例如,我使用
CONCAT()。使用以下示例,您应该能够使用第一个答案完成此操作:

CONCAT("Queue 1 (IN:", MAX(CASE WHEN SensorName = 'Queue 1' THEN TrafficIN END), " / OUT:",MAX(CASE WHEN SensorName = 'Queue 1' THEN TrafficOut END),")") AS "",
就像我说的,这只是获取数据的另一种方式

更新:在看到关于流量整形器的评论后,我将其添加到查询中,以便于:

SELECT `Location`,
CONCAT("Queue 1 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 1', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 1', `TrafficOUT`, 0)),") Shaper:", (SELECT `Sensors`.`TrafficShaper` FROM `Sensors` WHERE `Sensors`.`SensorName` = 'Queue 1')) AS `Queue 1`,
CONCAT("Queue 2 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 2', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 2', `TrafficOUT`, 0)),") Shaper:", (SELECT `Sensors`.`TrafficShaper` FROM `Sensors` WHERE `Sensors`.`SensorName` = 'Queue 2')) AS `Queue 2`,
CONCAT("Queue 3 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 3', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 3', `TrafficOUT`, 0)),") Shaper:", (SELECT `Sensors`.`TrafficShaper` FROM `Sensors` WHERE `Sensors`.`SensorName` = 'Queue 3')) AS `Queue 3`,
CONCAT("Queue 4 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 4', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 4', `TrafficOUT`, 0)),") Shaper:", (SELECT `Sensors`.`TrafficShaper` FROM `Sensors` WHERE `Sensors`.`SensorName` = 'Queue 4')) AS `Queue 4`,
CONCAT("Queue 5 (IN:", MAX(IF(`Sensors`.`SensorName` = 'Queue 5', `TrafficIN`, 0)), " / OUT:", MAX(IF(`Sensors`.`SensorName` = 'Queue 5', `TrafficOUT`, 0)),") Shaper:", (SELECT `Sensors`.`TrafficShaper` FROM `Sensors` WHERE `Sensors`.`SensorName` = 'Queue 5')) AS `Queue 5`
FROM `Locations` 
JOIN `Sensors` ON `Sensors`.`LocationsID` = `Locations`.`ID`
JOIN `SensorRawData` ON `SensorRawData`.`SensorID` = `Sensors`.`SensorID`
WHERE `SensorRawData`.`TimeStamp` BETWEEN '2019-03-13 00:00:00' AND '2019-03-13 23:59:59'
-- ORDER BY `Locations`.`Location`, `Sensors`.`Queue`
GROUP BY `Locations`.`Location`
这将产生以下输出:

| Location | Queue 1                                          | Queue 2                                          | Queue 3                                          | Queue 4                                          | Queue 5                                           |
| -------- | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------- |
| Voorburg | Queue 1 (IN:1.475493 / OUT:1.977284) Shaper:2048 | Queue 2 (IN:0.272115 / OUT:0.266318) Shaper:8192 | Queue 3 (IN:0.057073 / OUT:0.044036) Shaper:5120 | Queue 4 (IN:0.174479 / OUT:7.849057) Shaper:2048 | Queue 5 (IN:10.067641 / OUT:3.057053) Shaper:3072 |

排队的队伍能超过5个吗?你到底想要什么?我有点忙confused@Tom我想连接这些表,这样我就可以得到我提到的输出。还有一种可能创建3个不同的查询。但这不是它应该走的路。@nick,目前只有5个队列,但将来可能会有更多。@JayBlanchard感谢您编辑我的帖子并更改图像!有5个以上的队伍吗?你到底想要什么我有点confused@Tom我想连接这些表,这样我就可以得到我提到的输出。还有一种可能创建3个不同的查询。但这不是它应该走的路。@nick,目前只有5个队列,但将来可能会有更多。@JayBlanchard感谢您编辑我的帖子并更改图像!感谢您提供第二个解决方案!。。。我会调查的:)谢谢你提供第二个解决方案!。。。我将对此进行研究:)关于此解决方案的另一个问题,我如何为队列/传感器选择流量整形器?@Marvin我已再次更新演示以给出整形器值:关于此解决方案的另一个问题,我如何为队列/传感器选择流量整形器?@Marvin我已再次更新演示以给出整形器值: