如何撰寫一個程序,以便在添加新插入時,適當地添加行?
假設我有一張桌子:
create table test_table
(
code varchar2(10) not null,
type varchar2(50) not null,
start_date date not null,
end_date date not null,
parameter number
);
1.第一個測驗用例:
在表中,我們有:
insert into test_table values ('CODE', 'a', to_date('01.01.2021', 'DD,MM,YYYY'), to_date('10.01.2021', 'DD,MM,YYYY'), 1);
[2021-01-01 - 2021-01-10] type = "a" 引數 = 1
當我們要插入時:
insert into test_table values ('CODE', 'a', to_date('01.01.2021', 'DD,MM,YYYY'), to_date('20.01.2021', 'DD,MM,YYYY'), 1)
[2021-01-11 - 2021-01-20] type = "a" 引數 = 1
*Result should be:
2021-01-01 - 2021-01-20 type = "a" parameter = 1*
2.第二個測驗用例:
在表中,我們有:
insert into test_table values ('CODE', 'a', to_date('01.01.2021', 'DD,MM,YYYY'), to_date('10.01.2021', 'DD,MM,YYYY'), 1)
[2021-01-01 - 2021-01-10] type = "a" 引數 = 1
當我們要插入時:
insert into test_table values ('CODE', 'a', to_date('06.01.2021', 'DD,MM,YYYY'), to_date('20.01.2021', 'DD,MM,YYYY'), 2)
[2021-01-06 - 2021-01-20] 型別 = "a" 引數 = 2
*in result we should have:
[2021-01-01 - 2021-01-05] type = "a" parameter = 1
[2021-01-06 - 2021-01-20] type = "a" parameter = 2*
3.第三個測驗用例:
在表中,我們有:
insert into test_table values ('CODE', 'a', to_date('01.01.2021', 'DD,MM,YYYY'), to_date('10.01.2021', 'DD,MM,YYYY'), 1)
[2021-01-01 - 2021-01-20] 型別 = "a" 引數 = 1
當我們要插入時:
insert into test_table values ('CODE', 'a', to_date('06.01.2021', 'DD,MM,YYYY'), to_date('15.01.2021', 'DD,MM,YYYY'), 2)
[2021-01-06 - 2021-01-15] type = "a" 引數 = 2
*in result we should have:
[2021-01-01 - 2021-01-05] type = "a" parameter = 1
[2021-01-06 - 2021-01-15] type = "a" parameter = 2
[2021-01-16 - 2021-01-20] type = "a" parameter = 1*
uj5u.com熱心網友回復:
INSERT當您插入一個完全包含在現有日期范圍中間的新日期范圍時,您需要:UPDATE現有范圍到該范圍在新范圍之前的部分;以及INSERT新范圍之后的現有范圍部分的新范圍。因此,您總共需要進行 3 次更改。
同樣,當您插入一個完全包含現有范圍的新日期范圍時,您需要:INSERT新范圍;和DELETE現有的范圍(或做一個單一的UPDATE宣告)。
MERGE您可以對所有這些操作使用單個陳述句:
MERGE INTO test_table dst
USING (
WITH new_data (code, type, start_date, end_date, parameter) AS (
SELECT 'CODE2', 'a', DATE '2021-01-01', DATE '2021-01-20', 2 FROM DUAL
)
SELECT NULL AS rid,
n.*,
0 AS status -- Insert
FROM new_data n
UNION ALL
-- Existing rows overlapping before
SELECT t.ROWID,
t.code,
t.type,
t.start_date,
n.start_date - INTERVAL '1' DAY,
t.parameter,
1 -- Update overlap before
FROM test_table t
INNER JOIN new_data n
ON ( t.start_date <= n.start_date
AND t.end_date >= n.start_date)
UNION ALL
SELECT t.ROWID,
t.code,
t.type,
n.end_date INTERVAL '1' DAY,
t.end_date,
t.parameter,
CASE
WHEN n.start_date <= t.start_date
AND t.end_date <= n.end_date
THEN 2 -- Delete
WHEN n.start_date < t.start_date
AND n.end_date > t.end_date
THEN 0 -- Insert overlap afterwards
ELSE 1 -- Update overlap afterwards
END
FROM test_table t
INNER JOIN new_data n
ON ( t.start_date <= n.end_date
AND t.end_date >= n.start_date)
WHERE NOT (t.start_date <= n.start_date AND t.end_date <= n.end_date)
) src
ON (src.rid = dst.ROWID AND status > 0)
WHEN MATCHED THEN
UPDATE
SET code = src.code,
start_date = src.start_date,
end_date = src.end_date
DELETE
WHERE status = 2
OR src.start_date > src.end_date
WHEN NOT MATCHED THEN
INSERT (code, type, start_date, end_date, parameter)
VALUES (src.code, src.type, src.start_date, src.end_date, src.parameter);
db<>在這里擺弄
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/434212.html
