我一直在尝试将Merge语句引入以下SQL查询,以便将记录更新或插入表快照,具体取决于是否可以针对基于BuildingId和Timestamp的现有记录找到匹配项。
基本上,查询通过基于BuildingId获取Snapshot表中的最新记录来创建基于小时时间帧的记录快照,并且它们会计算该小时内的所有值。
-- DECLARE TABLE VARIABLES TO HOLD TEMP DATA
DECLARE @Output table
(
SnapshotId bigint,
BuildingId bigint,
[TimeStamp] datetime
);
-- INSERT ACCUMULATIVE SNAPSHOT DATA INTO BMS_Snapshot TABLE
;WITH Snap (BuildingId, Timestamp_Actual, TimestampRange_Start, TimestampRange_End) AS
(SELECT BMS_Snapshot.BuildingId, MAX(BMS_Snapshot.Timestamp) AS Timestamp_Actual,
dateadd(hh, datediff(hh,0, MAX(BMS_Snapshot.Timestamp)), 0) AS TimestampRange_Start,
dateadd(mi, +59 , dateadd(hh, datediff(hh,0, MAX(BMS_Snapshot.Timestamp)), 0)) AS TimestampRange_End
FROM BMS_Snapshot
GROUP BY BMS_Snapshot.BuildingId)
INSERT INTO BMS_Snapshot
(BuildingId, Timestamp, Emissions, EnergyUse, NABERS, Lighting, Heating,
Cooling, InternalEquipment, Fans, WaterSystems, NotClassified, Electricity,
Gas, Water, Other, [Range])
OUTPUT inserted.SnapshotId, inserted.BuildingId, inserted.TimeStamp INTO @Output
SELECT [Snapshot].BuildingId,
MAX(TimestampRange_End) AS Timestamp,
SUM([Snapshot].Emissions) AS Emissions,
SUM([Snapshot].EnergyUse) AS EnergyUse,
AVG([Snapshot].NABERS) AS NABERS,
SUM([Snapshot].Lighting) AS Lighting,
SUM([Snapshot].Heating) AS Heating,
SUM([Snapshot].Cooling) AS Cooling,
SUM([Snapshot].InternalEquipment) AS InternalEquipment,
SUM([Snapshot].Fans) AS Fans,
SUM([Snapshot].WaterSystems) AS WaterSystems,
SUM([Snapshot].NotClassified) AS NotClassified,
SUM([Snapshot].Electricity) AS Electricity,
SUM([Snapshot].Gas) AS Gas,
SUM([Snapshot].Water) AS Water,
SUM([Snapshot].Other) AS Other,
1 AS [Range]
FROM
Snap INNER JOIN
BMS_Snapshot AS [Snapshot] ON Snap.BuildingId = [Snapshot].BuildingId
WHERE
/* RANGE - FILTER ONLY 10 MINUTE SNAPSHOTS */
[Snapshot].[Range] = 0 AND
[Snapshot].[TimeStamp]
BETWEEN TimestampRange_Start AND TimestampRange_End
GROUP BY [Snapshot].BuildingId
我已经尝试将合并声明放在一起,但似乎可以让更新与“从...选择”
感谢。
编辑:
经过一些游戏后,我现在有了以下查询,如果它存在,它会更新正确的记录,但如果它不存在则不会插入:
-- INSERT ACCUMULATIVE SNAPSHOT DATA INTO BMS_Snapshot TABLE
;WITH Snap (BuildingId, Timestamp_Actual, TimestampRange_Start, TimestampRange_End) AS
(SELECT BMS_Snapshot.BuildingId, MAX(BMS_Snapshot.Timestamp) AS Timestamp_Actual,
dateadd(hh, datediff(hh,0, MAX(BMS_Snapshot.Timestamp)), 0) AS TimestampRange_Start,
dateadd(mi, +59 , dateadd(hh, datediff(hh,0, MAX(BMS_Snapshot.Timestamp)), 0)) AS TimestampRange_End
FROM BMS_Snapshot
GROUP BY BMS_Snapshot.BuildingId)
MERGE INTO BMS_Snapshot AS t
USING
(SELECT [Snapshot].BuildingId,
MAX(TimestampRange_End) AS Timestamp,
SUM([Snapshot].Emissions) AS Emissions,
SUM([Snapshot].EnergyUse) AS EnergyUse,
AVG([Snapshot].NABERS) AS NABERS,
SUM([Snapshot].Lighting) AS Lighting,
SUM([Snapshot].Heating) AS Heating,
SUM([Snapshot].Cooling) AS Cooling,
SUM([Snapshot].InternalEquipment) AS InternalEquipment,
SUM([Snapshot].Fans) AS Fans,
SUM([Snapshot].WaterSystems) AS WaterSystems,
SUM([Snapshot].NotClassified) AS NotClassified,
SUM([Snapshot].Electricity) AS Electricity,
SUM([Snapshot].Gas) AS Gas,
SUM([Snapshot].Water) AS Water,
SUM([Snapshot].Other) AS Other,
1 AS [Range]
FROM
Snap INNER JOIN
BMS_Snapshot AS [Snapshot] ON Snap.BuildingId = [Snapshot].BuildingId
WHERE
/* RANGE - FILTER ONLY 10 MINUTE SNAPSHOTS */
[Snapshot].[Range] = 0 AND
[Snapshot].[TimeStamp]
BETWEEN TimestampRange_Start AND TimestampRange_End
GROUP BY [Snapshot].BuildingId) As s
ON t.BuildingId = s.BuildingId
WHEN MATCHED AND (t.Timestamp = s.Timestamp AND
t.[Range] = 1) THEN
UPDATE SET
t.Emissions = s.Emissions,
t.EnergyUse = s.EnergyUse,
t.NABERS = s.NABERS,
t.Lighting = s.Lighting,
t.Heating = s.Heating,
t.Cooling = s.Cooling,
t.InternalEquipment = s.InternalEquipment,
t.Fans = s.Fans,
t.WaterSystems = s.WaterSystems,
t.NotClassified = s.NotClassified,
t.Electricity = s.Electricity,
t.Gas = s.Gas,
t.Water = s.Water,
t.Other = s.Other
WHEN NOT MATCHED BY t THEN
INSERT
(BuildingId, Timestamp, EnergyUse, NABERS, Lighting, Heating,
Cooling, InternalEquipment, Fans, WaterSystems, NotClassified,
Electricity, Gas, Water, Other, [Range])
VALUES
(s.BuildingId, s.Timestamp, s.EnergyUse, s.NABERS, s.Lighting, s.Heating,
s.Cooling, s.InternalEquipment, s.Fans, s.WaterSystems, s.NotClassified,
s.Electricity, s.Gas, s.Water, s.Other, 1);
答案 0 :(得分:4)
MERGE BMS_Snapshot target USING (SELECT BMS_Snapshot.BuildingID, ...)
source(BuildingID,...)
ON target.BuildingID = source.BuildingID
AND target.Timestamp = source.Timestamp
WHEN MATCHED THEN
UPDATE SET Emissions = source.Emissions, ...
WHEN NOT MATCHED BY target THEN
INSERT (BuildingID, ...)
VALUES (source.BuildingID, ...);
我为这种格式道歉,因为我现在正在平板电脑上。
根据您的更新,您只在ON子句中查看buildingid,但您还需要时间戳。 buildingid匹配,但WHEN MATCHED上的过滤器将其从更新中删除。