如何选择最新值?

时间:2014-07-27 09:25:50

标签: sql sql-server

我有一个记录表,从许多探测器中收集值:

CREATE TABLE [Log]
(
  [LogID] int  IDENTITY (1, 1)   NOT NULL,
  [Minute] datetime  NOT NULL,
  [ProbeID] int   NOT NULL DEFAULT 0,
  [Value] FLOAT(24)  NOT NULL DEFAULT 0.0,

  CONSTRAINT Log_PK PRIMARY KEY([LogID])
)
GO

CREATE INDEX [Minute_ProbeID_Value] ON [Log]([Minute], [ProbeID], [Value])
GO

通常,每个探针每分钟左右生成一个值。一些示例输出:

LogID   Minute            ProbeID Value
======  ================  ======= =====
873875  2014-07-27 09:36  1972    24.4
873876  2014-07-27 09:36  2001    29.7
873877  2014-07-27 09:36  3781    19.8
873878  2014-07-27 09:36  1963    25.6
873879  2014-07-27 09:36  2002    22.9
873880  2014-07-27 09:36  1959    -30.1
873881  2014-07-27 09:36  2005    20.7
873882  2014-07-27 09:36  1234    23.8
873883  2014-07-27 09:36  1970    19.9
873884  2014-07-27 09:36  1991    22.4
873885  2014-07-27 09:37  1958    1.7
873886  2014-07-27 09:37  1962    21.3
873887  2014-07-27 09:37  1020    23.1
873888  2014-07-27 09:38  1972    24.1
873889  2014-07-27 09:38  3781    20.1
873890  2014-07-27 09:38  2001    30
873891  2014-07-27 09:38  2002    23.4
873892  2014-07-27 09:38  1963    26
873893  2014-07-27 09:38  2005    20.8
873894  2014-07-27 09:38  1234    23.7
873895  2014-07-27 09:38  1970    19.8
873896  2014-07-27 09:38  1991    22.7
873897  2014-07-27 09:39  1958    1.4
873898  2014-07-27 09:39  1962    22.1
873899  2014-07-27 09:39  1020    23.1

获得每个探针的最新读数的最有效方法是什么?

例如所需的输出(注意:"值"不是例如Max()或Avg()):

LogID   Minute             ProbeID  Value
======  =================  =======  =====
873899  27-Jul-2014 09:39  1020     3.1
873894  27-Jul-2014 09:38  1234     23.7
873897  27-Jul-2014 09:39  1958     1.4
873880  27-Jul-2014 09:36  1959     -30.1
873898  27-Jul-2014 09:39  1962     22.1
873892  27-Jul-2014 09:38  1963     26
873895  27-Jul-2014 09:38  1970     19.8
873888  27-Jul-2014 09:38  1972     24.1
873896  27-Jul-2014 09:38  1991     22.7
873890  27-Jul-2014 09:38  2001     30
873891  27-Jul-2014 09:38  2002     23.4
873893  27-Jul-2014 09:38  2005     20.8
873889  27-Jul-2014 09:38  3781     20.1

4 个答案:

答案 0 :(得分:2)

这是另一种方法

select *
  from log l
 where minute =
       (select max(x.minute) from log x where x.probeid = l.probeid)

您可以比较执行计划w / a fiddle - http://sqlfiddle.com/#!3/1d3ff/3/0

答案 1 :(得分:1)

试试这个:

SELECT T1.* 
FROM   Log T1 
       INNER JOIN (SELECT Max(Minute) Minute, 
                          ProbeID 
                   FROM   Log 
                   GROUP  BY ProbeID)T2 
               ON T1.ProbeID = T2.ProbeID 
                  AND T1.Minute = T2.Minute 

您可以在SQL Fiddle

上进行游戏

答案 2 :(得分:1)

您的问题是:“获得每个探针的最新读数的最有效方法是什么?”

要真正回答这个问题,请测试以测试不同的解决方案。我通常会使用@jyparask建议的row_number()方法。但是,以下可能具有更好的性能:

select l.*
from log l
where not exists (select 1
                  from log l2
                  where l2.probeid = l.probeid and
                        l2.minute > l.minute
                 );

为了提高性能,您需要log(probeid, minute)上的索引。

虽然不完全是您的问题,herenot exists在SQL Server上比其他方法表现更好的示例。

答案 3 :(得分:0)

;WITH MyCTE AS
(
    SELECT LogID,
           Minute,
           ProbeID,
           Value,
           ROW_NUMBER() OVER(PARTITION BY ProbeID ORDER BY Minute DESC) AS rn
    FROM   LOG
)
SELECT LogID,
       Minute,
       ProbeID,
       Value 
FROM   MyCTE
WHERE  rn = 1