如何在临时表

时间:2016-08-03 16:43:39

标签: sql-server tsql

我有2个表,一个包含日期范围和一个节点键,另一个包含与每个节点关联的系统中所有读数的组。我正在尝试找到最有效的方法来为每个节点找到最接近第一个表中指定范围的读数(第一个和最后一个)。

阅读表由以下内容组成:

                   NodeID,Endtime,DataValue

另一张表包含:

                   EndpointID, NodeID, startDate, endDate

我正在寻找类似的东西:

                   EndpointId,
                   Node ID, 
                   Reading closest to and >= start date,
                   Reading closest to and <= end date 

下面的脚本做了我想要的但不是最有效的,因为即使在少量节点上,这个读取表也很大。

SELECT  t.EndpointID,
    t.SPCNodeID,
    b.FirstRead as First_Read_DateTime,
    c.LastRead as Last_Read_DateTime

FROM    #Temp1 t
LEFT JOIN (               
  Select t1.EndpointID,
         MIN(R.EndTime) FirstRead
 From Reading R,
      #Temp1 t1
 Where      t1.SPCNodeID = R.NodeID
 AND        R.EndTime >= t1.First_Date_In_Range  
 AND        R.EndTime <= t1.Last_Date_In_Range  
 Group By t1.EndpointID      
) as b
on  t.EndpointID = b.EndpointID     

LEFT JOIN (  
 Select t1.EndpointID,
        MAX(R.EndTime) LastRead
 From Reading R,
      #Temp1 t1
 Where      t1.SPCNodeID = R.NodeID
 AND        R.EndTime >= t1.First_Date_In_Range  
 AND        R.EndTime <= t1.Last_Date_In_Range  
 Group By t1.EndpointID  
 ) as c
 on  t.EndpointID = c.EndpointID    

 ORDER BY t.EndpointID, Last_Date_In_Range DESC

我觉得有一种更好的方法可以做到这一点,效率更高,但我却无法想出来。

2 个答案:

答案 0 :(得分:0)

寻找这样的东西?:

SELECT  t.EndpointID,
    t.SPCNodeID,
    First_Read_DateTime,
    Last_Read_DateTime
FROM #Temp1 as t
OUTER APPLY (
    SELECT MAX(R.EndTime) as Last_Read_DateTime FROM Reading as r 
    WHERE t.SPCNodeID = R.NodeID and R.EndTime <= t.Last_Date_In_Range
) as rmax
OUTER APPLY (
    SELECT MIN(R.EndTime) as Last_Read_DateTime FROM Reading as r 
    WHERE t.SPCNodeID = R.NodeID and R.EndTime >= t.First_Date_In_Range
) as rmin

不保证其工作,只是一个想法。

答案 1 :(得分:0)

我认为你不需要两个左外连接,你可以在同一个子查询中确定MIN()和MAX()值(如果有的话):

SELECT  
    t.EndpointID,
    t.SPCNodeID,
    FirstRead as First_Read_DateTime,
    LastRead as Last_Read_DateTime
FROM    
    #Temp1 t    LEFT JOIN 
    (Select t1.EndpointID,
         MIN(R.EndTime) FirstRead,
         MAX(R.EndTime) LastRead
     From 
        Reading R inner join      
        #Temp1 t1    on 
          t1.SPCNodeID = R.NodeID   AND        
          R.EndTime >= t1.First_Date_In_Range AND        
          R.EndTime <= t1.Last_Date_In_Range  
     Group By t1.EndpointID) as b on  
    t.EndpointID = b.EndpointID 
ORDER BY t.EndpointID, Last_Date_In_Range DESC