2015-11-03 50 views
0

我試圖刪除表中的行,只有當有一個負值的相應條目。棘手的部分是可能會有更積極的消極或更積極的消極。如何在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

可以通過使用PL/SQL腳本2個步驟做,但它將具有比特的性能不佳,表格大小(行數)是多少? – nabeel

回答

2

還向我道歉。我意識到海報數據集太簡單了。我相信這是一個經過修改的答案。

基本上,需要分割爲對,然後刪除對具有總和()= 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; 
+0

如果您在示例中添加另一個包含「abcde 40」的行,結果如何?根據這個問題,你可能會保持0,1,2,..包含保存id值 – nabeel

+0

你的行是絕對正確的。 (感謝不downvoting)。我正在更新我的答案... –