Reputation: 3435
We have a source table where keep the raw data:
SourceTable
SD Product P1 P2
'01-Mar-2013' 'Prod1' 1 2
'02-Mar-2013' 'Prod1' 3 4
'03-Mar-2013' 'Prod1' 5 6
'04-Mar-2013' 'Prod1' 7 8
'04-Mar-2013' 'Prod2' 6 5
And we have the destination table like below:
DestinationTable
SD Product P1 P2 Active
'01-Mar-2013' 'Prod1' 9 10 1
I am trying to write a query which will process the data from the source table for each day for each Product and insert all the new rows into destination table, but we should also update the Active column(s) to 0 in the dest. table if the matching row is found in the source (this is determined if the SD and Product columns exists in the destination).
After processing the data the DestinationTable should look like this:
SD Product P1 P2 Active
'01-Mar-2013' 'Prod1' 9 10 0
'01-Mar-2013' 'Prod1' 1 2 1
'02-Mar-2013' 'Prod1' 3 4 1
'03-Mar-2013' 'Prod1' 5 6 1
'04-Mar-2013' 'Prod1' 7 8 1
'04-Mar-2013' 'Prod2' 6 5 1
I have tried to do this with MERGE but you can't update and insert at the same time when there is a match found.
MERGE DestinationTable AS d
USING (SELECT SD, Product, P1, P2 FROM SourceTable) AS s ON d.Product = s.Product AND s.SD = d.SD
WHEN MATCHED THEN UPDATE SET d.P1 = s.P1,
d.P2 = sdsP2
d.Active = 0
WHEN NOT MATCHED THEN
INSERT(SD,Product, P1, P2, Active)
VALUES(s.SD, s.Product, s.P1, s.P2, 1);
I have actually done what I wanted to do in SQL using OUTPUT statement however this is for Oracle 10g and Oracle does not have OUTPUT the same as SQL.
Is there any other way of achieving this. This does not have to be done with MERGE, I am open for any other solutions.
Thanks
Upvotes: 2
Views: 165
Reputation: 146349
What you want to do is
source
into destination
destination.active
column for any which match records in source
As you rightly point out, you can't do this with MERGE because MERGE wants to do an update when it finds a matched record not an update and an insert.
So I think you're stuck with doing this as two statements: update destination
first then insert the records from source
.
Both UPDATE and INSERT support the RETURNING clause, which will allow you to collect identifiers (and other columns) for rows updated or inserted. It's in the documentation: find out more.
Upvotes: 4
Reputation: 782
why not run 2 queries?
UPDATE DestinationTable
SET Active = 0
WHERE EXISTS (SELECT 1
FROM SourceTable
WHERE DestinationTable.Product = SourceTable.Product AND
DestinationTable.SD = SourceTable.SD)
Upvotes: 2