简体   繁体   中英

Update a table from another table but also insert

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

What you want to do is

  1. insert all the records from source into destination
  2. update the 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 .

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM