A表 aid name
1 KLK
2 KSS
3 LKI
……
N ADD
B表 bid name_id ports
1 1 9089
2 1 8089
3 1 7089
4 2 6077
5 2 7077
6 3 8900
……
查询结果要求为:
aid bid ports
1 1 9089
2 4 6077
3 6 8900
查询语句设计
select * from a ,(select * from b b1
where not exists (select 1 from b b2 where b1.name_id=b2.name_id and b1.id >b2.id))
where a.id=b.name_id
个人对上述查询的理解
把 not exists 换成 not in 来理解下
select * from b b1
where not in(select 1 from b b2 where b1.name_id=b2.name_id and b1.id >b2.id))
再把not in 换成in 来考虑下
select * from b b2 where b1.name_id=b2.name_id and b1.id >b2.id
再把上述语句转换成内连接查询来考虑下
select b1.id,b1.name_id,b2.id from b b1, b b2
where b1.name_id=b2.name_id
b1.id | b1.name_id | b2.id |
1 | 1 | 1 |
1 | 1 | 2 |
1 | 1 | 3 |
2 | 1 | 1 |
2 | 1 | 2 |
2 | 1 | 3 |
3 | 1 | 1 |
3 | 1 | 2 |
3 | 1 | 3 |
4 | 2 | 4 |
4 | 2 | 5 |
5 | 2 | 4 |
5 | 2 | 5 |
6 | 3 | 6 |
上表就是我们连接查询得到的结果,通过筛选条件 b1.id>b2.id得到的结果即为红色标记部分的结果
现在考虑
not in 的作用了,这里我们就当成整条记录 作为not in 的主语
理解 select * from b b1 where not in (红色标记部分组合成的结果)可以简单理解为,从表b的 6条记录中取出 不是红色标记的部分,
即从表B中去掉(id=2 and name_id=1)( id=3 and name_id=1)( id=5 and name_id=2) 这3条记录。
感觉我把这玩意弄复杂了。