我試圖刪除表中的行,只有當有一個負值的相應條目。棘手的部分是可能會有更積極的消極或更積極的消極。如何在Oracle SQL中刪除相應的匹配行?
value1 amt
12345 50
12345 50
12345 -50
12345 -50
abcde 40
abcde 40
abcde -40
11111 30
11111 -30
11111 -30
結果應該是:
abcde 40
11111 -30
我試圖刪除表中的行,只有當有一個負值的相應條目。棘手的部分是可能會有更積極的消極或更積極的消極。如何在Oracle SQL中刪除相應的匹配行?
value1 amt
12345 50
12345 50
12345 -50
12345 -50
abcde 40
abcde 40
abcde -40
11111 30
11111 -30
11111 -30
結果應該是:
abcde 40
11111 -30
還向我道歉。我意識到海報數據集太簡單了。我相信這是一個經過修改的答案。
基本上,需要分割爲對,然後刪除對具有總和()= 0。
create table t (id varchar2(20), val number);
delete from t;
INSERT INTO t (id, val) values ('12345', 50);
INSERT INTO t (id, val) values ('12345', 50);
INSERT INTO t (id, val) values ('12345', -50);
INSERT INTO t (id, val) values ('12345', -50);
INSERT INTO t (id, val) values ('abcde', 40);
INSERT INTO t (id, val) values ('abcde', 40);
INSERT INTO t (id, val) values ('abcde', 20);
INSERT INTO t (id, val) values ('abcde', 40);
INSERT INTO t (id, val) values ('abcde', -40);
INSERT INTO t (id, val) values ('11111', 30);
INSERT INTO t (id, val) values ('11111', -30);
INSERT INTO t (id, val) values ('11111', -30);
INSERT INTO t (id, val) values ('aaaaa', 10);
INSERT INTO t (id, val) values ('aaaaa', -30);
COMMIT;
MERGE INTO t
USING (WITH value_partition AS
(SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY t.id, t.val ORDER BY ROWID) rn_in_value
FROM t)
SELECT sp.ROWID row_id,
sp.*,
CASE WHEN SUM (sp.val) OVER (PARTITION BY sp.id, ABS (sp.val), rn_in_value) = 0 THEN 'N' ELSE 'Y' END
keep_row
FROM value_partition sp) u
ON (t.ROWID = u.row_id
AND u.keep_row = 'N')
WHEN MATCHED THEN
UPDATE SET t.val = u.val
DELETE
WHERE u.keep_row = 'N';
SELECT * FROM t;
如果您在示例中添加另一個包含「abcde 40」的行,結果如何?根據這個問題,你可能會保持0,1,2,..包含保存id值 – nabeel
你的行是絕對正確的。 (感謝不downvoting)。我正在更新我的答案... –
可以通過使用PL/SQL腳本2個步驟做,但它將具有比特的性能不佳,表格大小(行數)是多少? – nabeel