Sql server SQL Server-从选择查询合并插入/更新

Sql server SQL Server-从选择查询合并插入/更新,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我一直在尝试在下面的SQL查询中引入一个Merge语句,以更新记录或将记录插入表快照,这取决于是否可以根据BuildingId和时间戳找到与现有记录的匹配 从本质上讲,查询通过基于BuildingId获取快照表中的最新记录,并将该小时内的所有值相加,从而基于小时时间框架创建记录的快照 -- DECLARE TABLE VARIABLES TO HOLD TEMP DATA DECLARE @Output table ( SnapshotId bigint,

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

从本质上讲,查询通过基于BuildingId获取快照表中的最新记录,并将该小时内的所有值相加,从而基于小时时间框架创建记录的快照

-- 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
我已经试着把merge语句放在一起,但似乎可以让更新使用“selectfrom…”来工作

谢谢

编辑:

经过一番尝试后,我现在有了以下查询,如果存在,它会更新正确的记录,但如果不存在,则不会插入:

    -- 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);
我为这种格式道歉,因为我现在正在使用平板电脑

根据您的更新,您只需要查看ON子句中的buildingid,但还需要时间戳。buildingid匹配,但匹配时的过滤器会将其从更新中删除

我为这种格式道歉,因为我现在正在使用平板电脑


根据您的更新,您只需要查看ON子句中的buildingid,但还需要时间戳。buildingid匹配,但“匹配时”上的筛选器会将其从更新中删除。

您是在尝试使用MERGE语句,还是仅执行“upsert”?您是在尝试使用MERGE语句,还是仅执行“upsert”?格式化您的帖子。我也在使用平板电脑。:-)格式化你的帖子。我也在使用平板电脑。:-)
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, ...);