帮助SQL查询

时间:2010-11-11 15:11:49

标签: sql

我有一个包含此架构的表:

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。

每台设备每天都会记录累计值。

请注意设备在几天内记录相同值时的问题... 也不要假设我们每天都有阅读。我们可能在记录的日子里有差距。

任何帮助将不胜感激,

感谢。

4 个答案:

答案 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。

此外,您没有说明每个设备是否每天限制为一条记录。

假设如下:

  1. 每台设备每天只有一个读数。
  2. 每个日期都有阅读。
  3. 第X天的StartValue比第X-1天的EndValue多.0001。
  4. 然后您可以使用类似以下查询的内容:

    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的列。