在一对多表中查找重复项

时间:2018-10-05 16:06:22

标签: sql sql-server

我有一个非常简单的表:

create table #Person_Tasks( Person_ID int, Task_ID int)

我想找到所有从事完全相同任务的人。例如,P1在T1和T2上工作。我如何才能找到仅在T1和T2上工作过的所有其他人?

以下是一些示例数据:

insert into #Person_Tasks
values
(0,0),
(0,1),
(0,2),
(1,0),
(1,1),
(1,3),
(2,0),
(2,1),
(2,2)

在此示例中,只有P0和P2具有完全相同的任务。 P1的任务数量相同,但是一个任务与其他人的任务ID不匹配。

表很大,可以容纳1000人和100K任务。

2 个答案:

答案 0 :(得分:4)

这里是一种方法,假设这些行是唯一的:

with pt as (
      select pt.*, count(*) over (partition by person_id) as num_tasks
      from person_tasks pt
     )
select pt.person_id, pt2.person_id
from pt left join
     pt pt2
     on pt2.task_id = pt.task_id and pt.person_id <> pt2.person_id
group by pt.person_id, pt2.person_id, pt.num_tasks, pt2.num_tasks
having (count(*) = pt.num_tasks and pt.num_tasks = pt2.num_tasks) or
       pt2.person_id is null

这会进行自我连接,然后计算每对匹配的次数。如果所有计数都匹配,那么这两个人将执行相同的任务。

这是db<>fiddle,显示它正常工作。

答案 1 :(得分:0)

根据您的示例,它也可以正常工作:

SELECT Person_ID
FROM (
    SELECT *,
    COUNT(Task_ID) OVER(PARTITION BY Person_ID) cnt
    FROM Person_Tasks
    WHERE 
        Task_ID IN(1,2)
) D 
WHERE 
    cnt > 1
GROUP BY Person_ID