2012-05-24 5 views
0

Я пытаюсь ввести оператор Merge в следующий SQL-запрос, чтобы либо обновить, либо вставить запись в таблицу моментального снимка в зависимости от соответствия между существующей записью на BuildingId и Timestamp.SQL Server - Merge Insert/Update from Select query

По существу, запрос создает моментальный снимок записей на основе часового периода времени, путем получения последней записи в таблице моментальных снимков на основе 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 

Я попытался положить вместе заявление слияния, но может показаться, чтобы иметь возможность получить обновление для работы с «Select From ...»

Спасибо.

EDIT:

После некоторых играли вокруг, теперь у меня есть следующий запрос, который делает обновление правильную запись, если она существует, но не вставить, если не существует:

-- 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

Вы пытаетесь использовать инструкцию MERGE или просто выполнить «upsert»? –

ответ

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, ...); 

Приносим извинения за формат, поскольку я сейчас на планшете.

за ваше обновление, вы смотрите только на buildid в предложении ON, но вам также нужна ваша метка времени. Соединитель buildingid, но фильтр на WHEN MATCHED удаляет его из обновления.

+1

Отформатировал сообщение. Я тоже на планшете. :-) –