遇到这么一条SQL语句,百思不得其要领,贴出来求高手解释
if not object_id('Tempdb..#T') is null
drop table #T
Go
Create table #T([ID] int,[Name] nvarchar(1),[Memo] nvarchar(2))
Insert #T
select 1,N'A',N'A1' union all
select 2,N'A',N'A2' union all
select 3,N'A',N'A3' union all
select 4,N'B',N'B1' union all
select 5,N'B',N'B2'
Go
语句
Select * from #T a where not exists(select 1 from #T where Name=a.Name and ID<a.ID) 为什么最后显示的结果是将相同NAME字段的最小ID查找出来了呢?
请高手指点,谢谢
if not object_id('Tempdb..#T') is null
drop table #T
Go
Create table #T([ID] int,[Name] nvarchar(1),[Memo] nvarchar(2))
Insert #T
select 1,N'A',N'A1' union all
select 2,N'A',N'A2' union all
select 3,N'A',N'A3' union all
select 4,N'B',N'B1' union all
select 5,N'B',N'B2'
Go
语句
Select * from #T a where not exists(select 1 from #T where Name=a.Name and ID<a.ID) 为什么最后显示的结果是将相同NAME字段的最小ID查找出来了呢?
请高手指点,谢谢
====
这里最终要筛选的就是#T这张表,然后后面的not exists相当于一个过滤条件,
not exists ID<a.ID就是说不存在比#T中ID还小的ID,
所以最后得到就是#T中Name相同,ID最小的记录啦。
好好体会。
*
from
#T a --别名
where
not exists(select 1 from #T where Name=a.Name and ID<a.ID) ---子查询---在子查询中 当name与外面查询的相同时,ID小于#T表的ID
--not exists表示不存在
有个简单的方法
想象外面是个大记录集,大记录集里的每一条记录都拿到后面那个小查询去比对,符合条件(not exists)的记录留下,不符合的记录不要
Select * from #T a where not exists(select 1 from #T where Name=a.Name and ID<a.ID)
如果name相同,并且不存在比它小的id,就是最小的id了。
select 2,N'A',N'A2' union all
select 3,N'A',N'A3' union all
select 4,N'B',N'B1' union all
select 5,N'B',N'B2'
Select * from #T a where not exists(select 1 from #T where Name=a.Name and ID<a.ID)
关键是exists子查询,对每一条记录,子查询查找[name]字段相同,并且id值小于记录id的记录,如果查出记录,即not exists为假,只有找不到NAME相同且id号比其小的记录被查出,满足此条件的,只有id号最小的记录。
一条一条逐条查询可能更好理解,下面以name都是A的1,2,3条记录来说明
第1条,找不到id<1的记录,子查询不能返回记录,not exists成立,记录被查出,
第2条,可找到id<2的记录1,子查询返回记录,not exists不成立,此记录不会查出
第3条 可找到id<3的记录1,2,子查询返回记录,not exists不成立,此记录不会查出
2楼解释很清楚了Select * from #T a where not exists(select 1 from #T where Name=a.Name and ID<a.ID)
1 子查询是: 当两表name相同时,查询别名表a中id大于原表中id的数据
2 加not exists 就是查找别名表中a最小的http://topic.csdn.net/u/20100921/08/333dd048-7d41-45d3-9179-df0e6109c597.html
使用 EXISTS 和 NOT EXISTS 查找交集与差集
使用 EXISTS 和 NOT EXISTS 引入的子查询可用于两种集合原理的操作:交集与差集。两个集合的交集包含同时属于两个原集合的所有元素。差集包含只属于两个集合中的第一个集合的元素。city 列中 authors 和 publishers 的交集是作者和出版商共同居住的城市的集合。USE pubs
SELECT DISTINCT city
FROM authors
WHERE EXISTS
(SELECT *
FROM publishers
WHERE authors.city = publishers.city)下面是结果集:city
--------
Berkeley(1 row(s) affected)当然,该查询可以写成一个简单的联接。USE pubs
SELECT DISTINCT authors.city
FROM authors INNER JOIN publishers
ON authors.city = publishers.citycity 列中 authors 和 publishers 的差集是作者所居住的、但没有出版商居住的所有城市的集合,也就是除 Berkeley 以外的所有城市。USE pubs
SELECT DISTINCT city
FROM authors
WHERE NOT EXISTS
(SELECT *
FROM publishers
WHERE authors.city = publishers.city)该查询也可以写成:USE pubs
SELECT DISTINCT city
FROM authors
WHERE city NOT IN
(SELECT city
FROM publishers)
注意得引用不同别名,
大家讲的都很好,但6楼的老师讲的比较我比较容易理解,所以分数就给maco_wang,还是非常感谢各位老师,从你们的回复中学到不少东西,谢谢大家.