假设有一张表T描述了拥有书籍的人。字段是pid(人员ID),bid(书籍ID):
-----------
|pid | bid|
-----------
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 3 | 2 |
| 3 | 3 |
-----------
现在,我怎样才能找到所有没有共同书籍的人?在这个例子中,它应该返回(1,2)。
另外,如何确保不重复?例如,(1,2)和(2,1)是重复的。
答案 0 :(得分:2)
让我们创建一个与
一起玩的表格create table #temp1 (pid int, bid int)
insert into #temp1 (pid, bid) values (1,1)
insert into #temp1 (pid, bid) values (1,2)
insert into #temp1 (pid, bid) values (2,3)
insert into #temp1 (pid, bid) values (3,2)
insert into #temp1 (pid, bid) values (3,3)
步骤1.此查询查找共享书籍的所有人
select distinct t1.pid, t2.pid
FROM #temp1 t1
inner join #temp1 t2
on t1.bid = t2.bid AND t1.pid <> t2.pid
pid pid
----------- -----------
1 3
2 3
3 1
3 2
步骤2.但问题是值是重复的。我们可以通过确保一个pid小于另一个pid来排除它们。
select distinct t1.pid, t2.pid
FROM #temp1 t1
inner join #temp1 t2
on t1.bid = t2.bid AND t1.pid <> t2.pid
where t1.pid < t2.pid
pid pid
----------- -----------
1 3
2 3
现在问题是找到所有人并将他们从列表中排除,这些人有共同的书。
步骤3.我们可以获得所有人对
SELECT distinct t1.pid, t2.pid
FROM #temp1 t1, #temp1 t2
where t1.pid < t2.pid
pid pid
----------- -----------
1 2
1 3
2 3
步骤4.我们需要使用步骤3中的结果并排除步骤2中的结果
SELECT STEP4.* FROM
(SELECT distinct t1.pid AS PID1, t2.pid AS PID2
FROM #temp1 t1, #temp1 t2
where t1.pid < t2.pid) STEP4
WHERE NOT EXISTS (SELECT * FROM
(select distinct t1.pid AS PID1, t2.pid AS PID2
FROM #temp1 t1
inner join #temp1 t2
on t1.bid = t2.bid AND t1.pid <> t2.pid
where t1.pid < t2.pid) STEP2
where STEP2.PID1 = STEP4.PID1 AND STEP2.PID2 = STEP4.PID2)
PID1 PID2
----------- -----------
1 2