T-SQL - 仅获取所选条件的最新行

时间:2017-04-04 06:40:20

标签: sql-server tsql query-optimization

我的测量表有SERIAL_NBR列,DATE_TIME,VALUE。 有很多数据,所以当我需要它们来获得2000个设备的最后48小时

Select * from MY_TABLE where [TIME]> = DATEADD (hh, -48, @TimeNow)

需要很长时间。 有没有办法不接收每个设备的所有行,但只有最新的条目?这会加快查询执行时间吗?

4 个答案:

答案 0 :(得分:3)

假设有一个名为deviceId的列(根据您的需要进行更改),您可以将top 1 with ties与窗口函数row_number一起使用:

Select top 1 with ties *
from MY_TABLE 
where [TIME]> = DATEADD (hh, -48, @TimeNow)
Order by row_number() over (
                    partition by deviceId
                    order by Time desc
                );

答案 1 :(得分:1)

您列出的列值与您的代码不完全匹配,因此您可能需要稍微更改此代码,但听起来对于每个SERIAL_NBR,您希望在过去48小时内记录的DATE_TIME最高。这应该会为你实现这个结果。

SELECT SERIAL_NBR,DATE_TIME,VALUE
FROM MY_TABLE AS M
WHERE M.DATE_TIME >= DATEADD(hh,-48,@TimeNow)
    AND M.DATE_TIME = (SELECT MAX(_M.DATE_TIME) FROM MY_TABLE AS _M WHERE M.SERIAL_NBR = _M.SERIAL_NBR)

答案 2 :(得分:1)

您只需创建公用表表达式即可对条目进行排序和分组,然后从中选择最新的条目。

;WITH numbered
   AS ( SELECT [SERIAL_NBR], [TIME], [VALUE], row_nr = ROW_NUMBER() OVER (PARTITION BY [SERIAL_NBR] ORDER BY [TIME] DESC)
          FROM MY_TABLE 
         WHERE [TIME]> = DATEADD (hh, -48, @TimeNow) )
SELECT [SERIAL_NBR], [TIME], [VALUE]
  FROM numbered
 WHERE row_nr = 1 -- we want the latest record only

根据数据量和可用指数,这可能会或可能不会比Anthony Hancock的答案更快。

与他的回答类似,您也可以尝试以下方法: (从MSSQL的角度来看,下面的查询和Anthony的查询非常相同,他们可能最终会得到相同的查询计划)

SELECT [SERIAL_NBR] , [TIME], [VALUE]
  FROM MY_TABLE AS M
  JOIN (SELECT [SERIAL_NBR] , max_time = MAX([TIME])
          FROM MY_TABLE 
         GROUP BY [SERIAL_NBR]) AS L -- latest
    ON L.[SERIAL_NBR] = M.[SERIAL_NBR]
   AND L.max_time     = M.[TIME]
 WHERE M.DATE_TIME >= DATEADD(hh,-48,@TimeNow)

答案 3 :(得分:0)

这将为您提供每个序列号的最新记录的详细信息:

  Select t.SERIAL_NBR, q.FieldsYouWant
  from MY_TABLE t
  outer apply
  (
    selct top 1 t2.FieldsYouWant
    from MY_TABLE t2 
    where t2.SERIAL_NBR = t.SERIAL_NBR
    order by t2.[TIME] desc
  )q
  where t.[TIME]> = DATEADD (hh, -48, @TimeNow)

另外,值得将DATEADD (hh, -48, @TimeNow)放入变量而不是计算内联。