根据多列删除重复项

时间:2017-01-03 02:15:08

标签: sql sql-server ssms

我使用以下内容列出了重复项:

select s.MessageId, t.* 
from Message s
join (
    select ToUserId, FromUserId, count(*) as qty
    from Message
    group by ToUserId, FromUserId
    having count(*) > 1
) t on s.ToUserId = t.ToUserId and s.FromUserId = t.FromUserId

现在,我如何删除除一条消息之外的所有消息(我试图删除重复消息,以便我可以在FromUserId and ToUserId上应用唯一索引。)

2 个答案:

答案 0 :(得分:18)

使用cte并指定行号,以便删除除重复对之外的所有行号。

with rownums as 
(select m.*, 
 row_number() over(partition by ToUserId, FromUserId order by ToUserId, FromUserId) as rnum
 from Message m)
delete r
from rownums r
where rnum > 1

答案 1 :(得分:0)

制作样本数据

    DECLARE @Message TABLE(ID INT ,ToUserId varchar(100),FromUserId varchar(100))
    INSERT INTO @Message(ID,ToUserId, FromUserId )
    VALUES  ( 1,'abc',  'def'  ), ( 2,'abc',  'def'  ), ( 3,'abc',  'def'  ), ( 4,'qaz',  'xsw'  )

- 删除数据

    DELETE m FROM @Message AS m 
    INNER JOIN (
         SELECT *,row_number()OVER(PARTITION BY ToUserId,FromUserId ORDER BY ID ) AS rn FROM @Message AS m
    ) t ON t.ID=m.ID
    WHERE t.rn>1

    SELECT * FROM @Message
----------- ---------- ----------
1           abc        def
4           qaz        xsw

如果没有列表示将行指定为ID,则可以尝试使用行的地址(例如%% lockres %%)

    DELETE m FROM @Message AS m 
    INNER JOIN (
        SELECT *,row_number()OVER(PARTITION BY ToUserId,FromUserId ORDER BY %%lockres%% ) AS rn FROM @Message AS m
    ) t ON t.ID=m.ID
    WHERE t.rn>1

    SELECT *, %%lockres%% FROM @Message