理解SQL语句中 Exists()

理解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
*/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值