Trigger to update existing data or insert if data does not exist (multi-row suppport)

sql, sql-server-2008, triggers

Solution

Try to Use Merge Statement.

Visit http://blog.sqlauthority.com/2008/08/28/sql-server-2008-introduction-to-merge-statement-one-statement-for-insert-update-delete/

Hope, this will help.

Problem

I have two tables, both tables contain similar columns of "username", "Date" and "Time". One table (table 2) is essentially a summation of the 'time' column per date where table1 can have multiple "time's" per date. I have no control over any statements used to insert data into table1 so I thought the best way to do this would be to use a trigger on table1 which inserts into or updates table2 depending on whether a row is already there for the date(s) inserted. To do this, something similar to the following would be fine: ``` IF NOT EXISTS(SELECT * FROM table2 WHERE date = @date/*date from inserted*/) --insert into table 2 here ELSE --update table 2 here ``` However, the problem is that I also need multi-row support on the trigger which would result in the previous `IF` failing. One idea would be to loop each row of the insert but from what I've read this will have a big impact on performance which I want to avoid (this is a last resort if there is no better way). So, is there a way to do what I need without using a some kind of loop? An example insert which I would be using: ``` INSERT INTO table2 (username, date, time) SELECT i.username, i.date, SUM(w.time) FROM inserted AS i JOIN (SELECT username, date, time FROM table1/*table with trigger*/) AS w ON w.date = i.date AND w.username = i.username GROUP BY i.username, i.date ``` Thanks in advance for any advice! Note: I'm new to SQL so sorry if I'm missing anything/making obvious mistakes! EDIT (Solution): The working solution (thanks to the answer by @Ronak Vyas) is as follows: ``` MERGE table2 AS m USING (SELECT i.username, i.date, SUM(w.time) FROM inserted AS i JOIN (SELECT username, date, time FROM table1/*table with trigger*/) AS w ON w.date = i.date AND w.username = i.username GROUP BY i.username, i.date) AS s ON m.date = s.date AND m.username = s.username WHEN MATCHED THEN UPDATE SET m.duration = s.duration WHEN NOT MATCHED THEN INSERT (username, date, time) VALUES (s.username, s.date, s.time) ``` Thanks a lot!

Original source