(這是假設你是在DB2 for Linux的/ UNIX/Windows的,其他平臺可能略有不同)
DELETE FROM
(SELECT ROWNUMBER() OVER (PARTITION BY ONE, TWO, THREE) AS RN
FROM SESSION.TEST) AS A
WHERE RN > 1;
應該給你,你在找什麼。
該查詢使用OLAP functionROWNUMBER()
到每個ONE
,TWO
,THREE
組合內分配一個編號爲每一行。然後,DB2能夠將fullselect
(A)引用的行與DELETE
statement應從表中刪除的行匹配。爲了能夠使用fullselect
作爲刪除子句的目標,它必須符合deletable view的規則(請參閱註釋部分下的「可刪除視圖」)。
下面是一些證據(上LUW 9.7測試):
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEST (
one CHAR(2),
two CHAR(2),
three CHAR(2),
name CHAR(3)
) ON COMMIT PRESERVE ROWS;
INSERT INTO SESSION.TEST VALUES
('A1', 'B1', 'C1', 'xyz'),
('A1', 'B1', 'C1', 'pqr'),
('A1', 'B1', 'C1', 'lmn'),
('A2', 'B2', 'C2', 'abc'),
('A2', 'B2', 'C2', 'def'),
('A3', 'B3', 'C3', 'ghi');
DELETE FROM
(SELECT ROWNUMBER() OVER (PARTITION BY ONE, TWO, THREE) AS RN
FROM SESSION.TEST) AS A
WHERE RN > 1;
SELECT * FROM SESSION.TEST;
編輯2017年3月2日:
針對艾哈邁德·安華的問題,如果你需要捕獲什麼被刪除,你也可以將刪除與「data change statement」結合起來。在這個例子中,你可以做類似以下,這將使你的「RN」一欄,一個,和:
SELECT * FROM OLD TABLE (
DELETE FROM
(SELECT
ROWNUMBER() OVER (PARTITION BY ONE, TWO, THREE) AS RN
,ONE
,TWO
,THREE
FROM SESSION.TEST) AS A
WHERE RN > 1
) OLD;
爲什麼你更喜歡{pqr,lmn}以上的xyz和高於def的abc?第一個首選項是按字母順序排列的,第一個是第一個。對我沒有意義。 – wildplasser 2012-04-10 11:24:56
@wildplasser:名稱列在後續步驟中無關緊要。所以沒有這樣的偏好...任何兩個都可以刪除.. – Nik 2012-04-10 11:27:14