sql - 在单个查询中从DB2中的表中删除重复的行

标签 sql db2 sql-delete

我有一个3列的表格,如下所示:

one   |   two    |  three  |   name
------------------------------------
 A1       B1          C1        xyz
 A1       B1          C1        pqr      -> should be deleted
 A1       B1          C1        lmn      -> should be deleted
 A2       B2          C2        abc
 A2       B2          C2        def      -> should be deleted
 A3       B3          C3        ghi
------------------------------------ 

该表没有任何主键列。我对表没有任何控制,因此无法添加任何主键列。

如图所示,我要删除一列,两列和三列的组合相同的行。因此,如果A1B1C1发生了三次(例如上述情况),则应删除另外两个,而仅保留一个。

如何仅通过DB2中的一个查询来实现这一目标?

我的要求是进行单个查询,因为我将通过Java程序运行它。

最佳答案

(这假设您使用的是DB2 Linux/Unix/Windows版,其他平台可能会略有不同)

DELETE FROM
    (SELECT ROWNUMBER() OVER (PARTITION BY ONE, TWO, THREE) AS RN
     FROM SESSION.TEST) AS A
WHERE RN > 1;

应该可以为您提供所需的东西。

该查询使用OLAP function ROWNUMBER()为每个ONETWOTHREE组合中的每一行分配一个数字。然后,DB2能够将fullselect(A)引用的行与 DELETE statement应该从表中删除的行进行匹配。为了能够将fullselect用作delete子句的目标,它必须与deletable view的规则匹配(请参阅“注释”部分下的“可删除 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日:

为了回答艾哈迈德·安瓦尔(Ahmed Anwar)的问题,如果您需要捕获已删除的内容,也可以将删除与“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;

关于sql - 在单个查询中从DB2中的表中删除重复的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10087527/

相关文章:

java - 如何使用 SmartGWT 和 SQL 实现惰性列表

php - MySQL 与字段中的保留字匹配

sql - SQL中的集合和库有区别吗?

sql - Postgres : delete rows order by without primary key

mysql - 如何删除没有临时表的 MySQL 表中的所有重复记录

Mysql 删除某个字段的接近重复项

MySQL 分组依据和位置

mysql - SQL - SELECT 中的 SELECT

database - 使用 MAX() 方法重新启动表的初始 ID

java - 启动连接池时出现NullPointerException