0

我一直在尝试在以下 SQL 查询中引入 Merge 语句,以更新或将记录插入到表快照中,具体取决于是否可以根据 BuildingId 和时间戳找到现有记录的匹配项。

本质上,该查询通过获取基于 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);
4

1 回答 1

3
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 上的过滤器将其从更新中删除。

于 2012-05-24T01:19:35.330 回答