zwz_good  

理解SQL语句中 Exists()

exists对于主查询而言只有一个作用:返回ture或false,而其本身查询的結果集不具任何意义
因此在子查询的Select命令语句的字段行中通常使用通用字符*或者直接使用数字1

执行步骤:
实际上是主查询每一次得到一条记录时,都会去判断where后面的条件是否都满足,如果满足了,那么这条记录将会作为结果返回。

比如有如下数据
表 Tb
 col
100001
100002
100003
100004
100008
100012
100013
100014
100023
100030
100031
100032
一 需要查询出col字段的连续序号的最小值
即希望返回数据集
100001
100008
100012
100023
100030

  第一步
  select col from tb a
  where exists(select * from tb where col=a.col-1)
返回数据集
100002
100003
100004
100013
100014
100031
100032
  该语句的理解为主查询每一次得到一条记录时,都会去判断where后面的条件是否都满足,如果满足,条件为真,则该记录作为结果返回.
  执行步骤
  当主查询在第一条记录时 100001,该记录是否返回取决于子查询的结果集是否为空即条件是否为真.
  select * from tb where col = 100000  (100001-1)
  结果集为空,条件为假,则该记录不返回.
  第二条记录 100002
  select * from tb where col = 100001  (100002-1)
  结果集不为空,条件为真,则该记录返回.
  ...
  第五条记录 100008
  select * from tb where col = 100007  (100008-1)
  结果集为空,条件为假,则该记录不返回.
  ...
  第十二条记录 100032
  select * from tb where col = 100031  (100032-1)
  结果集不为空,条件为真,则该记录返回.


  第二步将第一步数据集的相反数据
  select col from tb a
  where not exists(select * from tb where col=a.col-1)
得到结果集
100001
100008
100012
100023
100030

二 在ProductCount,ProductCode,WorkstationCode字段值相同情况下,需要查询出ProductNum字段的连续序号的最小值

ProductNum ProductCount ProductCode WorkstationCode
0          200          301A00          13-10-01-1
1          100          001100          13-10-01-1
1          100          001100          13-14-01-1
2          100          001100          13-10-01-1
2          100          001100          13-14-01-1
3          100          001100          13-10-01-1
3          200          001100          13-14-01-1
4          200          001100          13-10-01-1
5          200          001100          13-10-01-1
6          200          001100          13-10-01-1
7          200          001100          13-10-01-1
8          100          001100          13-10-01-1
9          100          001100          13-10-01-1
10          100          001100          13-10-01-1
92126          100          001100          13-10-01-1

SQL语句为
SELECT *
FROM dbo.TbOrderDetails a
WHERE NOT EXISTS(
  SELECT * FROM dbo.TbOrderDetails
  WHERE (ProductNum = a.ProductNum-1) AND
        (ProductCount = a.ProductCount) AND
        (ProductCode = a.ProductCode) AND
        (WorkstationCode = a.WorkstationCode)
  )

====================================

以下是摘取其他网友的问题与解答,也是一个很好的示例

问题(网友lizh0103 )

表的结构如下:
A
ID  Num AddDate
1    5    2008-03-10 9:26:20
2    2    2008-03-10 9:26:22
3    2    2008-03-10 9:28:20
4    2    2008-03-15 10:26:20
5    6    2008-03-15  10:26:22 
查询结果
1    5    2008-03-10 9:26:20
2    2    2008-03-10 9:26:22
4    2    2008-03-15 10:26:20
5    6    2008-03-15  10:26:22 
我想从表中查询出 两条 adddate 时间在两秒以内的 数据

解答 (网友jinjazz )

--建立测试环境
set nocount on
create table test(ID varchar(20),Num varchar(20),AddDate varchar(20))
insert into test select '1','5','2008-03-10 9:26:20'
insert into test select '2','2','2008-03-10 9:26:22'
insert into test select '3','2','2008-03-10 9:28:20'
insert into test select '4','2','2008-03-15 10:26:20'
insert into test select '5','6','2008-03-15 10:26:22'
go
--测试
select * from test a
    where exists(select 1 from test where id<>a.id
        and abs(datediff(s,a.AddDate,AddDate))<=2)


--删除测试环境
drop table test
set nocount off

/*
1    5    2008-03-10 9:26:20
2    2    2008-03-10 9:26:22
4    2    2008-03-15 10:26:20
5    6    2008-03-15 10:26:22
*/

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zwzgood/archive/2009/06/17/4275409.aspx

posted on 2009-06-17 10:07  zwz_good  阅读(534)  评论(0编辑  收藏  举报