使用MySQL将一个表连接到另一个表中的最新行

时间:2011-04-12 11:53:14

标签: mysql join one-to-many

我希望以特殊方式加入两个表格,第一个表格是设备,其中包含设备列表。

第二个表是数据记录,每当设备中的设备被轮询时,就会存储数据的提升。

设备表:

+----------+------------+----------------------------+---------------------+
| deviceId | deviceName | deviceDescription          | timeCreated         |
+----------+------------+----------------------------+---------------------+
|        1 | System 1   | Main System in Server Room | 2010-01-01 00:00:00 |
|        2 | System 2   | Outdoor System             | 2010-01-01 00:00:00 |
+----------+------------+----------------------------+---------------------+

DataLog表:

+----+---------------------+----------+-----------+---------+
| id | time_stamp          | DeviceId | FuelLevel | Voltage |
+----+---------------------+----------+-----------+---------+
|  1 | 2010-01-01 00:00:00 |        1 |        60 |     220 |
|  2 | 2010-01-01 00:00:00 |        2 |        20 |     221 |
|  3 | 2010-01-02 00:00:00 |        1 |       100 |     219 |
|  4 | 2010-01-02 00:00:00 |        2 |       100 |     222 |
|  5 | 2010-01-03 00:00:00 |        1 |        80 |     219 |
|  6 | 2010-01-03 00:00:00 |        2 |        99 |     220 |
+----+---------------------+----------+-----------+---------+

目前,我使用 DataLog 表格中的查询获取每个设备的最新数据:

 Where DeviceId = 1 ORDER BY timestamp DESC LIMIT 1

我想要的是一个返回所有设备列表的查询,其中列与每个设备的最新数据一起加入,如下所示:

+----------+------------+----------------------------+---------------------+-----------+---------+
| deviceId | deviceName | deviceDescription          | time_stamp          |FuelLevel  | Voltage |
+----------+------------+----------------------------+---------------------+-----------+---------+
|        1 | System 1   | Main System in Server Room | 2010-01-03 00:00:00 |        80 |     219 |
|        2 | System 2   | Outdoor System             | 2010-01-03 00:00:00 |       99  |     220 |
+----------+------------+----------------------------+---------------------+-----------+---------+

4 个答案:

答案 0 :(得分:3)

你不能在外层做“限制1”,你失去你想要的东西......所有设备最后一次进入。对每个设备的最后一个ID使用预查询,然后加入...

select 
        Devices.*,
        DataLog.Time_Stamp,
        DataLog.FuelLevel,
        DataLog.Voltage
    from
        ( select DeviceID,
                 max( ID ) LastActionID
              from
                 DataLog
              group by 
                 1 ) LastInstance
        join DataLog
            on LastInstance.LastActionID = DataLog.ID
        join Devices 
            on LastInstance.DeviceID = Devices.DeviceID
   order by 
       Devices.DeviceName

根据你最后的评论,我实际上会改为......

使用“LastLogID”更新您的设备表。然后,通过触发器插入DataLog表,立即用新ID更新Device表...这样,您永远不需要直接预先查询数据日志..您已经拥有最后一个ID并运行从那直接到由该ID加入的数据日志。

答案 1 :(得分:1)

我知道它太可怕,不优雅且耗时,但这个查询有效:

SELECT deviceId,deviceName,deviceDescription,
  (SELECT time_stamp FROM datalog
    WHERE datalog.DeviceId=devices.deviceId
    ORDER BY time_stamp DESC LIMIT 0,1) time_stamp,
  (SELECT FuelLevel FROM datalog
    WHERE datalog.DeviceId=devices.deviceId
    ORDER BY time_stamp DESC LIMIT 0,1) FuelLevel,
  (SELECT Voltage FROM datalog
    WHERE datalog.DeviceId=devices.deviceId
    ORDER BY time_stamp DESC LIMIT 0,1) Voltage
FROM devices

我试图让一个子查询检索多个列,但MySql抱怨因为它只需要一列。

答案 2 :(得分:0)

  SELECT
  d.deviceId, d.deviceName, d.deviceDescription, 
  dl.time_stamp, dl.FuelLevel, dl.Voltage 
  FROM Device d, DataLog dl 
  WHERE d.deviceId=dl.deviceID 
  ORDER BY time_stamp DESC
  LIMIT 1

答案 3 :(得分:0)

顺便说一句,如果你只想要最新的行,那么你可以通过自动增量字段(datalog_table.id

进行搜索
SELECT dvc.deviceId,dvc.deviceName,dvc.deviceDescription,
       dtl.time_stamp,dtl.FuelLevel,dtl.Voltage 
FROM  device_table dvc
INNER JOIN datalog_table dtl
ON dtl.DeviceId=dvc.deviceId
ORDER BY dtl.id  LIMIT 1