0

我有两个表,ADDRESSES和一个附加表CONTACTS联系人有一个 SUPERID,即他们所属的地址的 ID。我想在地址表中识别重复项(相同的姓名、名字和生日),并将这些重复项的联系人合并到最新的地址(最新的DATECREATE或地址的最高ID)。之后将删除其他重复项。

不过,我合并联系人的方法不起作用。删除重复的作品。这是我的方法。将不胜感激支持这里有什么问题。谢谢!

      UPDATE dbo.CONTACTS
    SET SUPERID = ADDRESSES.ID FROM dbo.ADDRESSES
inner join CONTACTS on ADDRESSES.ID = CONTACTS.SUPERID
        WHERE ADDRESSES.id in (
    SELECT id  FROM dbo.ADDRESSES 
    WHERE EXISTS(
        SELECT NULL FROM ADDRESSES AS tmpcomment
               WHERE dbo.ADDRESSES.FIRSTNAME0 = tmpcomment.FIRSTNAME0
               AND dbo.ADDRESSES.LASTNAME0 = tmpcomment.LASTNAME0
               and dbo.ADDRESSES.BIRTHDAY1 = tmpcomment.BIRTHDAY1
               HAVING dbo.ADDRESSES.id > MIN(tmpcomment.id)
                       ))

        DELETE FROM ADDRESSES
    WHERE id in (
    SELECT id FROM dbo.ADDRESSES
          WHERE EXISTS(
        SELECT NULL FROM ADDRESSES AS tmpcomment
               WHERE dbo.ADDRESSES.FIRSTNAME0 = tmpcomment.FIRSTNAME0
               AND dbo.ADDRESSES.LASTNAME0 = tmpcomment.LASTNAME0
               and dbo.ADDRESSES.BIRTHDAY1 = tmpcomment.BIRTHDAY1
               HAVING dbo.ADDRESSES.id > MIN(tmpcomment.id)
                       )
                         )

这是一个用于理解问题的示例。

ADDRESSES

|    ID      | DATECREATE  |   LASTNAME0  | FIRSTNAME0  |    BIRTHDAY1 |
|:-----------|------------:|:------------:|------------:|:------------:|
| 1          |  19.07.2011 |     Arthur   |   James     |  05.05.1980  |
| 2          |  23.08.2012 |     Arthur   |   James     |  05.05.1980  |
| 3          |  11.12.2015 |     Arthur   |   James     |  05.05.1980  |
| 4          |  22.10.2016 |     Arthur   |   James     |  05.05.1980  |
| 6          |  20.12.2014 |     Doyle    |   Peter     |  01.01.1950  |
| 7          |  09.01.2016 |     Doyle    |   Peter     |  01.01.1950  |
|:-----------|------------:|:------------:|------------:|:------------:|

CONTACTS
|    ID      | SUPERID  |
|    1       |    1     |
|    2       |    1     |
|    3       |    2     |
|    4       |    2     |
|    5       |    3     |
|    6       |    4     |
|    7       |    4     |
|    8       |    6     |
|    9       |    6     |
|    10      |    6     |
|    11      |    7     |

结果应该是这样的

ADDRESSES
    |    ID      | DATECREATE  |   LASTNAME0  | FIRSTNAME0  |    BIRTHDAY1 |
    |:-----------|------------:|:------------:|------------:|:------------:|
    | 4          |  22.10.2016 |     Arthur   |   James     |  05.05.1980  |
    | 7          |  09.01.2016 |     Doyle    |   Peter     |  01.01.1950  |

    CONTACTS

    |    ID      | SUPERID  |
    |    1       |    4     |
    |    2       |    4     |
    |    3       |    4     |
    |    4       |    4     |
    |    5       |    4     |
    |    6       |    4     |
    |    7       |    4     |
    |    8       |    7     |
    |    9       |    7     |
    |    10      |    7     |
    |    11      |    7     |
4

1 回答 1

0

我的方法是使用临时表:

/*


CREATE TABLE addresses
([ID] int, [DATECREATE] varchar(10), [LASTNAME0] varchar(6), [FIRSTNAME0] varchar(5), [BIRTHDAY1] datetime);

INSERT INTO addresses
([ID], [DATECREATE], [LASTNAME0], [FIRSTNAME0], [BIRTHDAY1])
VALUES
(1, '19.07.2011', 'Arthur', 'James', '1980-05-05 00:00:00'),
(2, '23.08.2012', 'Arthur', 'James', '1980-05-05 00:00:00'),
(3, '11.12.2015', 'Arthur', 'James', '1980-05-05 00:00:00'),
(4, '22.10.2016', 'Arthur', 'James', '1980-05-05 00:00:00'),
(6, '20.12.2014', 'Doyle', 'Peter', '1950-01-01 00:00:00'),
(7, '09.01.2016', 'Doyle', 'Peter', '1950-01-01 00:00:00');


CREATE TABLE contacts
([ID] int, [SUPERID] int);

INSERT INTO contacts
([ID], [SUPERID])
VALUES
(1, 1),
(2, 1),
(3, 2),
(4, 2),
(5, 3),
(6, 4),
(7, 4),
(8, 6),
(9, 6),
(10, 6),
(11, 7);

*/


DROP TABLE IF EXISTS #t; --sqls2016+ only, google for an older method if yours is sub 2016
SELECT id as oldid, MAX(id) OVER(PARTITION BY lastname0, firstname0, birthday1) as newid INTO #t
FROM 
  addresses;

/*now #t contains data like 
1, 4
2, 4
3, 4
4, 4
6, 7
7, 7*/

--remove the ones we don't need to change
DELETE FROM #t WHERE oldid = newid;

BEGIN TRANSACTION;
SELECT * FROM addresses;
SELECT * FROM contacts;

--now #t is the list of contact changes we need to make, so make those changes
UPDATE contacts
SET contacts.superid = #t.newid
FROM
  contacts INNER JOIN #t ON contacts.superid = #t.oldid;

--now scrub the old addresses with no contact records. This catches all such records, not just those in #t
DELETE FROM addresses WHERE id NOT IN (SELECT DISTINCT superid FROM contacts);

--alternative to just clean up the records we affected in this operation
DELETE FROM addresses WHERE id IN (SELECT oldid FROM #t);

SELECT * FROM addresses;
SELECT * FROM contacts;
ROLLBACK TRANSACTION;

请注意,我已经对此进行了测试,它会产生您想要的结果,但我主张谨慎从互联网上复制更新/删除查询并运行。我插入了一个事务,它选择前后的数据并回滚事务,所以没有任何东西被破坏。首先在测试数据库上运行它!

于 2019-03-07T09:55:18.497 回答