从数据库

时间:2017-10-09 11:05:29

标签: sql-server

我对SQL很陌生,所以请耐心等待我!

我有一张桌子 - MeterData - 看起来像这样:

(我还会注意到,实际的数据库有160多个米ID,每个米ID有23个量,150万个+记录,每天都在增长!)

MeterID TimeStamp          Value Quantity
------------------------------------------
meter1  09/10/2017 07:00:00 2.3 Power
meter1  09/10/2017 07:15:00 2.4 Power 
meter1  09/10/2017 07:30:00 2.7 Power
meter1  09/10/2017 07:00:00 230 Voltage
meter1  09/10/2017 07:15:00 229 Voltage
meter1  09/10/2017 07:30:00 230 Voltage
meter1  09/10/2017 07:00:00 978 Energy
meter1  09/10/2017 07:15:00 979 Energy
meter1  09/10/2017 07:30:00 980 Energy
meter2  09/10/2017 07:00:00 15.8    Power 
meter2  09/10/2017 07:15:00 14.7    Power 
meter2  09/10/2017 07:30:00 18.9    Power 
meter2  09/10/2017 07:00:00 415 Voltage
meter2  09/10/2017 07:15:00 414 Voltage
meter2  09/10/2017 07:30:00 414 Voltage
meter2  09/10/2017 07:00:00 15687   Energy
meter2  09/10/2017 07:15:00 15688   Energy
meter2  09/10/2017 07:30:00 15689   Energy

我想查询数据库以返回具有最新时间戳的多个“值”,但是对于特定的“数量”和“MeterID”,例如我想要实现的结果应该是这样的:

Value   MeterID   Timestamp              Quantity
--------------------------------------------------
 2.7    meter1    09/10/2017 07:30:00    Power
18.9    meter2    09/10/2017 07:30:00    Power

如果我用这个查询数据库:

SELECT TOP 1 
    Value, MeterID, Timestamp, Quantity
FROM 
    MeterData
WHERE 
    MeterID = 'meter1' AND Quantity = 'Power'
ORDER BY 
    Timestamp DESC

我得到了所需的结果,但只有一个“MeterID”:

Value   MeterID   Timestamp             Quantity
------------------------------------------------
 2.7    meter1    09/10/2017 07:30:00   Power

但是如何获得多个MeterID的结果呢?显然,UNION条款不起作用,因为我有一个ORDER BY条款......我尝试过LAST_VALUEINNER JOIN

非常感谢提前!

1 个答案:

答案 0 :(得分:0)

使用带有ROW_NUmber的公用表表达式应​​该可行 使用上述问题的测试数据进行编辑

CREATE TABLE dbo.MeterData(
     MeterId NVARCHAR(20)
    ,TimeStamp  DATETIME
    ,Value      DECIMAL(10,2)
    ,Quantity   NVARCHAR(20)

)
INSERT INTO dbo.MeterData
( MeterId , TimeStamp , Value , Quantity)
VALUES
('meter1',  '09/10/2017 07:00:00', 2.3 ,'Power' ),
('meter1',  '09/10/2017 07:15:00', 2.4 ,'Power' ) ,
('meter1',  '09/10/2017 07:30:00', 2.7 ,'Power' ),
('meter1',  '09/10/2017 07:00:00',230 ,'Voltage'),
('meter1',  '09/10/2017 07:15:00',229 ,'Voltage'),
('meter1',  '09/10/2017 07:30:00',230 ,'Voltage'),
('meter1',  '09/10/2017 07:00:00',978, 'Energy'),
('meter1',  '09/10/2017 07:15:00',979, 'Energy'),
('meter1',  '09/10/2017 07:30:00',980, 'Energy'),
('meter2',  '09/10/2017 07:00:00',15.8 ,'Power' ) ,
('meter2',  '09/10/2017 07:15:00',14.7 ,'Power' ) ,
('meter2',  '09/10/2017 07:30:00',18.9 ,'Power' ) ,
('meter2',  '09/10/2017 07:00:00',415 ,'Voltage'),
('meter2',  '09/10/2017 07:15:00',414 ,'Voltage'),
('meter2',  '09/10/2017 07:30:00',414 ,'Voltage'),
('meter2',  '09/10/2017 07:00:00',15687, 'Energy'),
('meter2',  '09/10/2017 07:15:00',15688, 'Energy'),
('meter2',  '09/10/2017 07:30:00',15689, 'Energy')


;WITH cte
AS(
    SELECT *, RN = ROW_NUMBER()OVER(PARTITION BY MeterId, Quantity
                                    ORDER BY TimeStamp DESC)
    FROM dbo.MeterData
)
SELECT * FROM cte WHERE RN = 1