Skip to content
Advertisement

SQL query that will give me the RecordedValue range each device recorded for each date

I have a table with this schema:

DeviceID int
FloorID int
RoomID int
DateRecorded datetime
RecordedValue decimal

A sample of the table’s data looks like:

DeviceID   FloorID   RoomID   DateRecorded RecordedValue
0001       Floor 1   Room 1   1/1/2000     0 
0001       Floor 1   Room 1   1/2/2000     10.5000
0001       Floor 1   Room 1   1/3/2000     18.7500  
0002       Floor 1   Room 2   1/1/2000     10.0000 
0002       Floor 1   Room 2   1/2/2000     10.0000
0002       Floor 1   Room 2   1/3/2000     22.5000  

I need to build a query that will give me the RecordedValue range each device recorded for each date.

Something like:

DeviceID   FloorID   RoomID   DateRecorded  StartValue  EndValue
0001       Floor 1   Room 1   1/1/2000      NULL        0 
0001       Floor 1   Room 1   1/2/2000      0.0001      10.5000 
0001       Floor 1   Room 1   1/3/2000      10.5001     18.7500  
0002       Floor 1   Room 2   1/1/2000      NULL        10.0000 
0002       Floor 1   Room 2   1/2/2000      10.0000     10.0000 
0002       Floor 1   Room 2   1/3/2000      10.0001     22.5000   

So basically, it has to take the MIN from the previous day’s recording if exists or NULL and the MAX from the next day if exists or NULL.

Each device records the accumulated value each day.

Note the issue when the device records the same value for a few days… Also don’t assume that we get a reading every day. We may have gaps in the days recorded.

Advertisement

Answer

Your question isn’t entirely clear. You appear to be computing the start and end values from the previous day’s values according to some formula, but you don’t state what the formula is. for instance, it’s not clear to me why Dev 2 on 1/2/2000 has an end value of 22.4999 when the recorded value is 10.000.

Also, you don’t state whether each device is limited to a single record per day.

Assuming the following:

  1. Each device has only one reading per day.
  2. There is a reading every single date.
  3. The StartValue for day X is .0001 more than the EndValue for day X-1.

then you can use something like the following query:

SELECT D1.DeviceID, D1.FloorID, D1.RoomID, 
       D1.DateRecorded, D2.RecordedValue + .0001 AS StartValue,
       D1.RecordedValue AS EndValue
  FROM YourTable D1 INNER JOIN YourTable D2
  ON D1.DeviceID = D2.DeviceID AND D1.FloorID = D2.FloorID AND 
     D1.RoomID = D2.RoomID AND D1.DateRecorded = D2.DateRecorded+1

This will problems with the first or last day in the data set. You can solve that problem by switching to a LEFT or RIGHT OUTER JOIN, depending on whether you want the first or last date to appear.

Also note that you should factor out FloorID and RoomID from your recorded values table since they appear to depend on DeviceID. This will normalize your database, reduce storage, and simply the JOIN conditions in the query.

Edit in response to comments, below:

If assumption #2 (there’s a record for every day) is not valid, then you can use something like this revised version (also changed not to use the .0001 to generate a false start value):

SELECT D1.DeviceID, D1.FloorID, D1.RoomID, 
       D1.DateRecorded, D2.RecordedValue AS StartValue,
       D1.RecordedValue AS EndValue
  FROM YourTable D1 INNER JOIN YourTable D2
  ON D1.DeviceID = D2.DeviceID AND D1.FloorID = D2.FloorID AND 
     D1.RoomID = D2.RoomID AND D2.DateRecorded = 
       (SELECT MAX(DateRecorded) FROM YourTable 
          WHERE DeviceID = D1.DeviceID AND FloorID = D1.FloorID AND 
               RoomID = D1.RoomID AND DateRecorded < D1.DateRecorded)

And I’ll just rewrite this to show you how much smaller it is if you factor out the non-normalized columns:

SELECT D1.DeviceID, D1.FloorID, D1.RoomID, 
       D1.DateRecorded, D2.RecordedValue AS StartValue,
       D1.RecordedValue AS EndValue
  FROM YourTable D1 INNER JOIN YourTable D2
  ON D1.DeviceID = D2.DeviceID AND D2.DateRecorded = 
       (SELECT MAX(DateRecorded) FROM YourTable 
          WHERE DeviceID = D1.DeviceID AND DateRecorded < D1.DateRecorded)
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement