I have 2 tables:
Table 1: EnrollmentTransaction
(PK is both the column)
EnrollmentId | TransactionId
-------------+--------------
5 | 1
5 | 2
6 | 3
7 | 2
7 | 3
8 | 3
8 | 2
8 | 1
9 | 1
Table 2: EnrollmentDetail
(TransactionId
column added newly with default value 1 since it's not null column)
In this table PK are (EnrollmentId, ParameterId, SVCId and TransactionId )
EnrollmentId | ParameterId| SVCId| SVCValueId| TransactionId
-------------+------------+------+-----------+--------------
5 | 1 | 57 | 21 | 1
6 | 8 | 58 | 24 | 1
7 | 9 | 57 | 21 | 1
7 | 6 | 58 | 29 | 1
8 | 8 | 57 | 21 | 1
By referring to Table 1, I would like to insert if there is no combination of(EnrollmentId , TransactionId ) or update if there is an entry based on EnrollmentId
.
For example:
Scenario 1: EnrollmentId = 5
has 2 entries in table 1 whereas, table 2 has only 1 entry and I must insert one row with values 5, 1, 57, 21, 2 in table 2. I should not make any changes of the table 1 existing combination row (5, 1, 57, 21, 1). since it matches the combination of Enrollment Id and TrnasactionId.
Scenario 2: EnrollmentId = 6
has only 1 entry in both table 1 and table 2, but TransactionId is different in both the table. So I now have to refer table 1 for TransactionId and update in table 2. mainly TrasnactionId will be final value to update from the table 1. The final values of this row will be 6, 8, 58, 24 and 3.
Scenario 3: EnrollmentId = 9
has only 1 entry in table 1 and no entry found in the table 2. so I should not insert/update of this combination.
Logic considerations.
Note: Posible combination in table 1 for each enrollmentId will be 3 values. i.e 1, 2 or 3.
This is one time activity and it goes till production.
Final result will be like as below.
EnrollmentId | ParameterId| SVCId| SVCValueId| TransactionId
-------------+------------+---------------------------------
5 | 1 | 57 | 21 | 1
5 | 1 | 57 | 21 | 2
6 | 8 | 58 | 24 | 3
7 | 9 | 57 | 21 | 2
7 | 6 | 58 | 29 | 2
7 | 9 | 57 | 21 | 3
7 | 6 | 58 | 29 | 3
8 | 8 | 57 | 21 | 1
8 | 8 | 57 | 21 | 2
8 | 8 | 57 | 21 | 3
Is there any possibility to write a single query to achieve this? I have to achieve both insert and update in the same query.
Note: Oracle 19 is the database.
You can use a MERGE
statement and merge rows based on prioritising matching transactionid
values:
MERGE INTO enrollmentdetail dst
USING (
SELECT t.enrollmentid,
t.transactionid,
d.parameterid,
d.svcid,
d.svcvalueid,
d.rowid AS rid,
ROW_NUMBER() OVER (
PARTITION BY d.ROWID
ORDER BY CASE WHEN d.transactionid = t.transactionid THEN 0 ELSE 1 END
) AS rn
FROM enrollmenttransaction t
INNER JOIN enrollmentdetail d
ON t.enrollmentid = d.enrollmentid
) src
ON (dst.ROWID = src.rid AND src.rn = 1)
WHEN MATCHED THEN
UPDATE
SET parameterid = src.parameterid,
transactionid = src.transactionid,
svcid = src.svcid,
svcvalueid = src.svcvalueid
WHEN NOT MATCHED THEN
INSERT (enrollmentid, transactionid, parameterid, svcid, svcvalueid)
VALUES (src.enrollmentid, src.transactionid, src.parameterid, src.svcid, src.svcvalueid);
Which, for the sample data:
CREATE TABLE EnrollmentTransaction (EnrollmentId, TransactionId) AS
SELECT 5, 1 FROM DUAL UNION ALL
SELECT 5, 2 FROM DUAL UNION ALL
SELECT 6, 3 FROM DUAL UNION ALL
SELECT 7, 2 FROM DUAL UNION ALL
SELECT 7, 3 FROM DUAL UNION ALL
SELECT 8, 3 FROM DUAL UNION ALL
SELECT 8, 2 FROM DUAL UNION ALL
SELECT 8, 1 FROM DUAL UNION ALL
SELECT 9, 1 FROM DUAL;
CREATE TABLE EnrollmentDetail (
EnrollmentId, ParameterId, TransactionId, SVCId, SVCValueID
) AS
SELECT 5, 1, 1, 57, 21 FROM DUAL UNION ALL
SELECT 6, 8, 1, 58, 24 FROM DUAL UNION ALL
SELECT 7, 9, 1, 57, 21 FROM DUAL UNION ALL
SELECT 7, 6, 1, 58, 29 FROM DUAL UNION ALL
SELECT 8, 8, 1, 57, 21 FROM DUAL;
Then after the MERGE
the table contains:
ENROLLMENTID | PARAMETERID | TRANSACTIONID | SVCID | SVCVALUEID |
---|---|---|---|---|
5 | 1 | 1 | 57 | 21 |
5 | 1 | 2 | 57 | 21 |
6 | 8 | 3 | 58 | 24 |
7 | 9 | 2 | 57 | 21 |
7 | 6 | 2 | 58 | 29 |
7 | 9 | 3 | 57 | 21 |
7 | 6 | 3 | 58 | 29 |
8 | 8 | 1 | 57 | 21 |
8 | 8 | 2 | 57 | 21 |
8 | 8 | 3 | 57 | 21 |
Note: this gets the expected answer for your sample data; please validate the logic for other scenarios that are not present in your sample data as your logic is complicated and not easily expressed using SQL.