Question

I have a following tables:

sensors:

id  name  key   code
1   s1    abc   123
2   s2    def   456
3   s3    ghi   789

measurements:

id value sensor_id generated_at
1  1.0   1         2013-12-30 06:00:00
2  1.0   1         2013-12-30 06:01:00
3  1.0   1         2013-12-30 06:02:00
4  3.0   2         2013-12-30 07:00:00
5  3.0   2         2013-12-30 07:01:00
6  3.0   2         2013-12-30 07:05:00
7  5.0   3         2013-12-30 08:02:00
8  5.0   3         2013-12-30 08:03:00
9  5.0   3         2013-12-30 08:11:00
10 5.0   3         2013-12-30 08:15:00

What I want to do is to generate report with all sensors data and include first and last generated_at time for received measurements, so the result of MySQL request should look like:

id name key code first_value_generated_at last_value_generated_at
1  s1   abc 123  2013-12-30 06:00:00      2013-12-30 06:02:00
2  s2   def 456  2013-12-30 07:00:00      2013-12-30 07:05:00
3  s3   ghi 789  2013-12-30 08:02:00      2013-12-30 08:15:00

I would appreciate any help, thanks.

Was it helpful?

Solution

I don't think that LEFT JOIN is really necessary here (only in case when there more or less sensors.id than in measurements.sensor_id). SQL query is below :

SELECT
    s.id,
    s.name,
    s.key,
    s.code,
    m.first_value_generated_at,
    m.last_value_generated_at
FROM sensors s JOIN 
   (SELECT
      sensor_id,
      MIN(generated_at) as first_value_generated_at,
      MAX(generated_at) as last_value_generated_at
    FROM
      measurements
    GROUP BY
      sensor_id
   ) m ON s.id = m.sensor_id
ORDER BY
    s.id

OTHER TIPS

I hope this should work for you,

select *
    ,(select min(generated_at) from measurements as a where a.sensor_id =s.id) as first_value_generated_at 
    ,(select max(generated_at) from measurements as b where b.sensor_id =s.id) as last_value_generated_at
 from sensors as s

Try this query , it will generate the exact output you need

    select s.id,s.name,s.key,s.code,min(m.generated_at) first_vaue_generated_at,max(m.generated_at) last_value_generated_at
      from sensors s
 LEFT JOIN measurements m ON (s.id = m.sensor_id)
  group by 1,2,3,4;

Try this it will work

select s.id,s.name,s.key,s.code,m.generated_at as first_value_generated_at,ml.generated_at as last_value_generated_at from sensors as s,measurements as mf,measurements as ml where s.id = mf.sessor_id and s.id = ml.sensor_id and mf.generated_at < ml.generated_at group by mf.sensor_id  

Maybe this could do that - nested selects?

        select sensors.id, sensors.name, sensors.key, sensors.code,
     ( select generated_at from measurements order by time asc limit 1 )
 as first_value_generated_at,
     ( select generated_at  from measurements order by time desc limit 1 )
 as last_value_generated_at from sensors
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top