I need to extract data from the tables RawData and RawDataMeter and sum the ‘Value’ field for each unique MeterId for the last 10 minutes (relative to the TimeStamp). The RawData and RawDataMeter tables as joined via the RawDataId field using a INNER JOIN, records are only selected when the RawData.BuildingId and RawDataMeter.MeterId exist within the BuildingMeter table. I.e. the query needs select the fields from RawData and RawDataMeter tables only if they exist in the BuildingMeter table, it then needs to get the latest record for each meter (based on the TimeStamp) and then retrieve the last 10 minutes worth of values for that meter. Once it has these values, it needs to SUM each meters 10 minutes worth of values and output the results.
The query I have so far is:
SELECT TOP (SELECT COUNT(DISTINCT BuildingMeterId) FROM BuildingMeter)
MeterId, BuildingId, TimeStamp, Value
FROM
RawData
INNER JOIN
RawDataMeter
ON RawData.RawDataId = RawDataMeter.RawDataId
WHERE
EXISTS
(SELECT
BuildingId,
BuildingMeterId
FROM
BuildingMeter)
ORDER BY
TimeStamp DESC
Which produces the following results:
1 1 2012-05-16 12:51:00.000 216
2 1 2012-05-16 12:51:00.000 876989
3 1 2012-05-16 12:51:00.000 389164
4 1 2012-05-16 12:51:00.000 1.298896E+07
5 1 2012-05-16 12:51:00.000 283378
6 1 2012-05-16 12:51:00.000 1541438
7 1 2012-05-16 12:51:00.000 4241823
8 1 2012-05-16 12:51:00.000 5761659
9 1 2012-05-16 12:51:00.000 3
10 1 2012-05-16 12:51:00.000 0
11 1 2012-05-16 12:51:00.000 23
12 1 2012-05-16 12:51:00.000 3822836
13 1 2012-05-16 12:51:00.000 4983960
14 1 2012-05-16 12:51:00.000 909497
15 1 2012-05-16 12:51:00.000 7724438
BuildingMeter table sample (i’ve only included 1 building with 15 meters (this is variable)):
BuildingId BuildingMeterId
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
1 15
The sample data for the last 30 records from RawData:
RawDataId, TimeStamp, BuildingId
21677 2012-05-16 00:03:00.000 1
21678 2012-05-16 00:03:00.000 1
21679 2012-05-16 00:03:00.000 1
21680 2012-05-16 00:03:00.000 1
21681 2012-05-16 00:03:00.000 1
21682 2012-05-16 00:03:00.000 1
21683 2012-05-16 00:03:00.000 1
21684 2012-05-16 00:03:00.000 1
21685 2012-05-16 00:03:00.000 1
21686 2012-05-16 00:03:00.000 1
21687 2012-05-16 00:03:00.000 1
21688 2012-05-16 00:03:00.000 1
21689 2012-05-16 00:03:00.000 1
21690 2012-05-16 00:03:00.000 1
21691 2012-05-16 00:03:00.000 1
21662 2012-05-16 00:02:00.000 1
21663 2012-05-16 00:02:00.000 1
21664 2012-05-16 00:02:00.000 1
21665 2012-05-16 00:02:00.000 1
21666 2012-05-16 00:02:00.000 1
21667 2012-05-16 00:02:00.000 1
21668 2012-05-16 00:02:00.000 1
21669 2012-05-16 00:02:00.000 1
21670 2012-05-16 00:02:00.000 1
21671 2012-05-16 00:02:00.000 1
21672 2012-05-16 00:02:00.000 1
21673 2012-05-16 00:02:00.000 1
21674 2012-05-16 00:02:00.000 1
21675 2012-05-16 00:02:00.000 1
21676 2012-05-16 00:02:00.000 1
Sample for RawDataMeter:
MeterId, RawDataId, Value
15 21691 7722613
14 21690 908944
13 21689 4982947
12 21688 3821899
11 21687 6
10 21686 0
9 21685 0
8 21684 5761656
7 21683 4240048
6 21682 1541372
5 21681 283223
4 21680 1.298603E+07
3 21679 388137
2 21678 876121
1 21677 0
15 21676 7722615
14 21675 908944
13 21674 4982947
12 21673 3821899
11 21672 5
10 21671 0
9 21670 0
8 21669 5761656
7 21668 4240052
6 21667 1541372
5 21666 283223
4 21665 1.298604E+07
3 21664 388137
2 21663 876122
1 21662 0
EDIT:
Following the steps outlined by Gordon, I managed to get the following SQL query, which appears to be working correctly:
WITH
RawMeterData (MeterId, BuildingId, TimeStamp, LatestTimeStamp, Value) AS
(SELECT
RawDataMeter.MeterId,
RawData.BuildingId,
RawData.TimeStamp,
MAX(RawData.TimeStamp) OVER (PARTITION BY BuildingMeter.BuildingMeterId) AS LatestTimeStamp,
RawDataMeter.Value
FROM
BMS_RawData AS RawData
INNER JOIN
BMS_RawDataMeter AS RawDataMeter
ON RawData.RawDataId = RawDataMeter.RawDataId
INNER JOIN
(SELECT
DISTINCT BuildingId,
BuildingMeterId
FROM
AST_BuildingMeter) as BuildingMeter
ON RawData.BuildingId = BuildingMeter.BuildingId AND
RawDataMeter.MeterId = BuildingMeter.BuildingMeterId)
SELECT MeterId, BuildingId, SUM(Value) AS Value FROM RawMeterData WHERE RawMeterData.TimeStamp
BETWEEN DATEADD(mi, -9, LatestTimeStamp) AND LatestTimeStamp
GROUP BY MeterId, BuildingId
I don’t have enough time to write the query.
You need to do the following:
For writing the query, it would help if you put aliases in front of all the field names. The casual reader cannot tell which fields are from which tables.