Question

Having sensors spread around my house, they all send data to a mysql DB. Sensors send multiple samples per communication with the DB that occur every 5 minutes.

On table 'sensors' I have generic sensor info (primary key SensorId)

I need to pull the most recent SampleTime from the table 'sensordata' and also the most recent LastConnection from the table 'sensormonitoring' for each Distinct SensorId on table 'sensor'. So I can compare them with PHP.

Right now I'm doing this with whiles in PHP but I'm guessing there has to be an easier and more efficient way to do this with SQL (everytime I run the page 21 queries are done)

I have this:

SELECT SensorId FROM sensors

And then inside the while:

$query1 = "SELECT LastConnection
             FROM sensormonitoring
             WHERE SensorId =" . $row["SensorId"] . "
             ORDER BY LastConnection desc
             LIMIT 1";

$query2 = "SELECT SampleTime
             FROM sensordata
             WHERE SensorId =" . $row["SensorId"] ."
             ORDER BY SampleTime desc
             LIMIT 1";

Is there a way to do this with a single SQL query (perhaps with JOINS?) avoiding long PHP code?

Final result would be something like this

SensorId   LastConnection        SampleTime
----------------------------------------------------
01         2014-04-20 09:38:56   2014-04-20 09:30:00
02         2014-04-20 09:35:05   2014-04-19 10:15:00
03         2014-04-20 09:33:27   2014-04-20 09:26:00
04         2014-04-20 09:45:12   NULL

Just an extra explanation of my project: In this case I could see that Sensor 02 is having problems because the most recent samples are older than 15 minutes but is communicating fine with the DB; Sensor 04 is communicating but isn't collecting samples at all.

This also to say that: sometimes SampleTime might be NULL.

Was it helpful?

Solution

You should be able to do this all in one query by using MAX:

SELECT s.SensorId, MAX(m.LastConnection) AS LastConnection, MAX(d.SampleTime) AS SampleTime
FROM sensors s
  LEFT JOIN sensormonitoring m on (s.SensorId = m.SensorId)
  LEFT JOIN sensordata d on (s.SensorId = d.SensorId)
GROUP BY s.SensorId;

OTHER TIPS

This should be a working SQL statement that gives you all info you request: SELECT SensorId, (SELECT MAX(LastConnection) FROM sensormonitoring sm WHERE sm.SensorId = s.SensorId) AS LastConnection, (SELECT MAX(SampleTime) FROM sensordata sd WHERE sd.SensorId = s.SensorId) AS SampleTime FROM Sensors s

Try this

SELECT sensormonitoring.SensorId, sensormonitoring.LastConnection, sensordata.SampleTime
FROM sensormonitoring
INNER JOIN sensordata
ON sensormonitoring.SensorId=sensordata.SensorId;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top