我有一个包含此架构的表:
DeviceID int
FloorID int
RoomID int
DateRecorded日期时间
RecordedValue decimal
表格数据的样本如下:
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
我需要构建一个查询,它将为每个设备记录每个日期的RecordedValue范围。
类似的东西:
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
所以基本上,它必须从前一天的录音中取MIN(如果存在)或NULL,并且如果存在则为第二天的MAX或NULL。
每台设备每天都会记录累计值。
请注意设备在几天内记录相同值时的问题... 也不要假设我们每天都有阅读。我们可能在记录的日子里有差距。
任何帮助将不胜感激,
感谢。
答案 0 :(得分:0)
尝试:
SELECT DeviceID, DateRecorded, MIN(RecordedValue), MAX(RecordedValue)
FROM TableName
GROUP BY DeviceID, DateRecorded
ORDER BY 1, 2
答案 1 :(得分:0)
当你指出几天的重复值时,我不确定你想说的是什么。这是不正确的吗?
select DeviceID, min(RecordedValue), max(RecordedValue)
from yourtable
group by DeviceID, DateRecorded
答案 2 :(得分:0)
你的问题并不完全清楚。您似乎是根据某个公式计算前一天值的起始值和结束值,但是您没有说明公式是什么。例如,我不清楚当记录值为10.000时,为什么1/2 / 2000上的Dev 2的结束值为22.4999。
此外,您没有说明每个设备是否每天限制为一条记录。
假设如下:
然后您可以使用类似以下查询的内容:
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
这将导致数据集中第一天或最后一天出现问题。您可以通过切换到LEFT或RIGHT OUTER JOIN来解决该问题,具体取决于您是希望显示第一个还是最后一个日期。
另请注意,您应该从记录值表中分解FloorID和RoomID,因为它们似乎依赖于DeviceID。这将标准化您的数据库,减少存储,并简单地查询查询中的JOIN条件。
编辑以回应评论,如下所示:
如果假设#2(每天都有记录)无效,那么你可以使用类似这个修订版本的东西(也改为不使用.0001来生成错误的起始值):
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)
我只是重写这个,以显示如果你将非标准化列分解出来有多小:
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)
答案 3 :(得分:0)
这里你去:
SELECT DeviceID, FloorID, RoomdID, DateRecorded
, COALESCE((SELECT MAX(RecordedValue)
FROM RecordedValues a
WHERE a.DeviceID = b.DeviceID AND a.DateRecorded < b.DateRecorded), 0) AS StartValue
, (SELECT MAX(RecordedValue)
FROM RecordedValues a
WHERE a.DeviceID = b.DeviceID AND a.DateRecorded < b.DateRecorded) AS StartValueWithNulls
, Recordedvalue AS EndValue
FROM RecordedValues b
我不确定你是否真的想要返回NULL,所以我包含了一个用于处理StartValue的列。