が得られたものである 要件を正しく理解していれば、マージの代わりに挿入することでこれを行うことができます。サブクエリを拡張すると、destination
テーブルのデータに基づいて生成された 'sequence'値を持つすべてのsource
行を取得できます。いくつかのダミーデータを皮切り:
CREATE TABLE DESTINATION (GROUP_ID NUMBER, ADD_DATE DATE, SOME_TEXT VARCHAR2(20), TEXT_SEQ NUMBER);
INSERT INTO DESTINATION VALUES (42, DATE '2016-05-01', 'Foo 1', 1);
INSERT INTO DESTINATION VALUES (42, DATE '2016-05-01', 'Foo 2', 2);
INSERT INTO DESTINATION VALUES (42, DATE '2016-05-01', 'Foo 3', 3);
INSERT INTO DESTINATION VALUES (42, DATE '2016-05-02', 'Bar 1', 1);
CREATE TABLE SOURCE (GROUP_ID NUMBER, ADD_DATE DATE, SOME_TEXT VARCHAR2(20));
INSERT INTO SOURCE VALUES (42, DATE '2016-05-01', 'New foo 1');
INSERT INTO SOURCE VALUES (42, DATE '2016-05-01', 'New foo 2');
INSERT INTO SOURCE VALUES (42, DATE '2016-05-01', 'New foo 3');
INSERT INTO SOURCE VALUES (42, DATE '2016-05-02', 'New bar 1');
INSERT INTO SOURCE VALUES (42, DATE '2016-05-03', 'New baz 1');
INSERT INTO SOURCE VALUES (43, DATE '2016-05-02', 'New qux 1');
そして、現在の最大値を加えたグループ/日付のソースデータの解析行番号を使用して:
SELECT S.GROUP_ID, S.ADD_DATE, S.SOME_TEXT,
NVL(MAX(D.TEXT_SEQ), 0)
+ (ROW_NUMBER() OVER (PARTITION BY S.GROUP_ID, S.ADD_DATE ORDER BY 1)) AS TEXT_SEQ
FROM source s
LEFT JOIN destination d
ON D.GROUP_ID = S.GROUP_ID AND D.ADD_DATE = S.ADD_DATE
GROUP BY S.GROUP_ID, S.ADD_DATE, S.SOME_TEXT
/
GROUP_ID ADD_DATE SOME_TEXT TEXT_SEQ
---------- ---------- -------------------- ----------
42 2016-05-01 New foo 1 4
42 2016-05-01 New foo 2 5
42 2016-05-01 New foo 3 6
42 2016-05-02 New bar 1 2
42 2016-05-03 New baz 1 1
43 2016-05-02 New qux 1 1
あなたは、あなたの挿入のためにそれを使用することができます。あなたはまた、マージのusing
句と同じクエリを使用し、ON
句にA.TEXT_SEQ = B.TEXT_SEQ
を追加することができ
INSERT INTO destination (GROUP_ID ,ADD_DATE ,SOME_TEXT ,TEXT_SEQ)
SELECT ...
6 rows inserted.
SELECT GROUP_ID, ADD_DATE, TEXT_SEQ, SOME_TEXT
FROM DESTINATION
ORDER BY GROUP_ID, ADD_DATE, TEXT_SEQ;
GROUP_ID ADD_DATE TEXT_SEQ SOME_TEXT
---------- ---------- ---------- --------------------
42 2016-05-01 1 Foo 1
42 2016-05-01 2 Foo 2
42 2016-05-01 3 Foo 3
42 2016-05-01 4 New foo 1
42 2016-05-01 5 New foo 2
42 2016-05-01 6 New foo 3
42 2016-05-02 1 Bar 1
42 2016-05-02 2 New bar 1
42 2016-05-03 1 New baz 1
43 2016-05-02 1 New qux 1
。シーケンスがどのように生成されるかによってあなたは決して一致することはないので、あなたは常にWHEN NOT MATCHED
ブランチに入るので、ここで簡単な挿入には何も得られません。
(もちろん、複数のセッションで同時に宛先テーブルを変更することができますが、その問題はありますが、挿入/マージの手配が必要な場合はusing max(id) + 1
m isn't safe)
どのようなエラーが表示されますか? – Boneist
@Boneist SQLエラー:ORA-00904: "B"。 "ADD_DATE":無効な識別子 –
どのバージョンを使用していますか?それは11.2.0.4ではエラーではないようです。私は論理が理にかなっているかどうか分からない。グループ/日付にマッチするものがない場合、サブクエリ内のそのグループ/日付の現在の最大値は常にnullになりますか?そして、あなたのソースに同じグループ/日付の複数の行があった場合(マッチしないで、シーケンスがあれば)、マージはそれらのすべてに1の値を与えます。あなたはあなたがやっていることをあまりにも曖昧にしているのでしょうか? –