【问题标题】:Delete duplicates sql across multiple tables跨多个表删除重复的sql
【发布时间】:2015-03-13 02:57:52
【问题描述】:

我正在尝试从数据跨多个表的数据库中删除重复数据。

我有 3 个表,Person、Person_Address_Map 和 Address。我想删除除个人表中的所有重复行之外的所有重复行,但我还想检查地址数据是否相同(但不删除地址表中的任何行)。

我有以下内容可以删除我的 Person 表中的所有重复条目。

  DELETE
  FROM Person p
  WHERE EXISTS
    (SELECT 1 
    FROM Person temp
    Where p.name = temp.name AND
    p.id < temp.id);


 Person                    Person_Address_Map             Address
 | ID | Name | Age |       | Person_ID | Address_ID |     | ID | City | State |
 -------------------       --------------------------     ---------------------
 | 1  | Bob  |  20 |       |     1     |     1      |     | 1  | NYC  |  NY   | 
 | 2  | Bob  |  20 |       |     2     |     2      |     | 2  | NYC  |  NY   |
 | 3  | Jon  |  50 |       |     3     |     3      |     | 3  | LA   |  CA   | 
 | 4  | Jon  |  50 |       |     4     |     4      |     | 4  | SF   |  CA   |

例如,现在我的地址表有一个城市。 Person_Address_Map 包含个人 ID 和地址 ID。如何更改此查询,使其不仅检查 Person 的“名称”是否相等,而且还检查它们在 Address 表中映射到的“城市”是否相等? (不从地址表中删除任何数据)

删除并留下一个副本后,我希望在我的人员表中留下以下内容。 Person_Address_Map 也正在更新。

 Person                    Person_Address_Map             Address
 | ID | Name | Age |       | Person_ID | Address_ID |     | ID | City | State |
 -------------------       --------------------------     ---------------------
 | 1  | Bob  |  20 |       |     1     |     1      |     | 1  | NYC  |  NY   | 
                                                          | 2  | NYC  |  NY   |
 | 3  | Jon  |  50 |       |     3     |     3      |     | 3  | LA   |  CA   | 
 | 4  | Jon  |  50 |       |     4     |     4      |     | 4  | SF   |  CA   |

【问题讨论】:

  • 你最好显示你的表架构。
  • 您同时使用 SQL Server 和 Oracle?
  • 所以即使孩子现在是孤儿,您也想删除父行(Person)而不是子行(地址)?你对这些表有参照完整性吗?你有外键级联删除吗?如果没有,你打算如何处理这些新创建的孤儿?大部分问题都可以通过提供 ddl(包括外键和索引)以及一些示例数据来解决。 sqlfiddle.com 是一个很好的起点。
  • @SeanLange 我对 Person 和 Person_Address_Map 进行了级联删除。我用我正在寻找的更多内容更新了这个问题。
  • 这与查看实际表定义完全不同。但这里有什么问题。你说你有一个查询已经完成了我理解你想要的结果。

标签: sql oracle


【解决方案1】:

我想这应该可行,

DELETE
  FROM PERSON P
 WHERE EXISTS (SELECT 1
          FROM (WITH TABLE_ AS (SELECT P.ID,
                                       P.NAME,
                                       P.AGE,
                                       PERSON_ID,
                                       ADDRESS_ID,
                                       A.ID ADD_ID,
                                       A.CITY,
                                       A.STATE
                                  FROM PERSON             P,
                                       PERSON_ADDRESS_MAP PA,
                                       ADDRESS_           A
                                 WHERE P.ID = PA.PERSON_ID
                                   AND PA.ADDRESS_ID = A.ID)
                 SELECT A1.ID, TABLE_.NAME
                   FROM ADDRESS_ A1, TABLE_
                  WHERE TABLE_.ADD_ID != A1.ID
                    AND TABLE_.CITY = A1.CITY
                    AND TABLE_.STATE = A1.STATE) DELETABLE_
                  WHERE P.ID > DELETABLE_.ID
                    AND P.NAME = DELETABLE_.NAME
        );

这是我使用的表定义,

CREATE TABLE person (
         ID         NUMBER(5),
         NAME       VARCHAR2(15) ,
         AGE        NUMBER(3));
CREATE TABLE Person_Address_Map (
         Person_ID          NUMBER(5),
         Address_ID          NUMBER(5)
         );         
CREATE TABLE Address_ (
         ID         NUMBER(5),
         City        VARCHAR2(15) ,
         State        VARCHAR2(15));         

INSERT INTO person VALUES (1,'Bob',20);         
INSERT INTO person VALUES (2,'Bob',20);
INSERT INTO person VALUES (3,'Jon',50);
INSERT INTO person VALUES (4,'Jon',50);

INSERT INTO Person_Address_Map VALUES (1,1);
INSERT INTO Person_Address_Map VALUES (2,2);
INSERT INTO Person_Address_Map VALUES (3,3);
INSERT INTO Person_Address_Map VALUES (4,4);

INSERT INTO Address_ VALUES (1,'NYC','NY');
INSERT INTO Address_ VALUES (2,'NYC','NY');
INSERT INTO Address_ VALUES (3,'LA','CA');
INSERT INTO Address_ VALUES (4,'CA','CA');

我没有检查级联约束。我想它应该不会给你带来任何问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多