我的测量表有SERIAL_NBR列,DATE_TIME,VALUE。 有很多数据,所以当我需要它们来获得2000个设备的最后48小时
Select * from MY_TABLE where [TIME]> = DATEADD (hh, -48, @TimeNow)
需要很长时间。 有没有办法不接收每个设备的所有行,但只有最新的条目?这会加快查询执行时间吗?
答案 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)
放入变量而不是计算内联。