大家先不要管这两条查询语句的业务逻辑是什么,就看这两条语句为什么会返回不同的结果?
两条语句对应的exists完全相同,在我看来这两条语句是等价的呀。
--创建测试环境
create table #t1(编号 int,部门 varchar(10),日期1 datetime,状态 bit)
create table #t2(编号 int,部门 varchar(10),日期2 datetime,状态 bit)
create table #t3(编号 int,部门 varchar(10),日期 datetime)--插入测试数据
insert #t1(编号,部门,日期1,状态)
select '10001','01','2007-02-02','0' union all
select '10002','01','2007-02-06','0' union all
select '10003','02','2007-02-01','0' union all
select '10006','02','2007-03-02','0' union all
select '10001','03','2007-03-01','0' union all
select '10005','03','2007-03-01','0'insert #t2(编号,部门,日期2,状态)
select '10003','02','2007-02-10','1'insert #t3(编号,部门,日期)
select '10001','01','2007-02-03' union all
select '10002','01','2007-02-10' union all
select '10003','02','2007-02-06' union all
select '10006','02','2007-03-02' union all
select '10001','03','2007-03-01' union all
select '10005','03','2007-02-22' union all
select '10005','03','2007-03-02'--求解过程1
select *
from #t3 t3
where exists(
select 1
from #t1 t1
where not exists--如果表1中有2个以上相同编号则以日期1最大的为条件
(select 1 from #t1 where 编号 = t1.编号 and 日期1 > t1.日期1)
and t3.编号 = t1.编号 and t3.部门 = t1.部门--表3中的编号和部门同时存在表1中
and not exists--表3中的编号和部门同时表2中不存在
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门)
)
union allselect *
from #t3 t3
where exists(
select 1
from #t1 t1
where not exists--如果表1中有2个以上相同编号则以日期1最大的为条件
(select 1 from #t1 where 编号 = t1.编号 and 日期1 > t1.日期1)
and t3.编号 = t1.编号 and t3.部门 = t1.部门--表3中的编号和部门同时存在表1中
and exists--表3中的编号和部门同时存在表2中
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门)
and not exists--当表1.max(日期1)>表2.max(日期2)才满足条件
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门 and 日期2 >= t1.日期1)
)
/*--测试结果
编号 部门 日期
----------- ---------- -------------------------
10002 01 2007-02-10 00:00:00.000
10006 02 2007-03-02 00:00:00.000
10001 03 2007-03-01 00:00:00.000
10005 03 2007-02-22 00:00:00.000
10005 03 2007-03-02 00:00:00.000(所影响的行数为 5 行)
*/-------------------------------------------------------------------------------求解过程2
select *
from #t3 t3
where exists(
select 1
from #t1 t1
where not exists--如果表1中有2个以上相同编号则以日期1最大的为条件
(select 1 from #t1 where 编号 = t1.编号 and 日期1 > t1.日期1)
and t3.编号 = t1.编号 and t3.部门 = t1.部门--表3中的编号和部门同时存在表1中
and not exists--表3中的编号和部门同时表2中不存在
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门)
)
or exists(
select 1
from #t1 t1
where not exists--如果表1中有2个以上相同编号则以日期1最大的为条件
(select 1 from #t1 where 编号 = t1.编号 and 日期1 > t1.日期1)
and t3.编号 = t1.编号 and t3.部门 = t1.部门--表3中的编号和部门同时存在表1中
and exists--表3中的编号和部门同时存在表2中
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门)
and not exists--当表1.max(日期1)>表2.max(日期2)才满足条件
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门 and 日期2 >= t1.日期1)
)
--删除测试环境
drop table #t1,#t2,#t3/*--测试结果
编号 部门 日期
----------- ---------- -----------------------------
10002 01 2007-02-10 00:00:00.000
10003 02 2007-02-06 00:00:00.000
10006 02 2007-03-02 00:00:00.000
10001 03 2007-03-01 00:00:00.000
10005 03 2007-02-22 00:00:00.000
10005 03 2007-03-02 00:00:00.000(所影响的行数为 6 行)
*/
两条语句对应的exists完全相同,在我看来这两条语句是等价的呀。
--创建测试环境
create table #t1(编号 int,部门 varchar(10),日期1 datetime,状态 bit)
create table #t2(编号 int,部门 varchar(10),日期2 datetime,状态 bit)
create table #t3(编号 int,部门 varchar(10),日期 datetime)--插入测试数据
insert #t1(编号,部门,日期1,状态)
select '10001','01','2007-02-02','0' union all
select '10002','01','2007-02-06','0' union all
select '10003','02','2007-02-01','0' union all
select '10006','02','2007-03-02','0' union all
select '10001','03','2007-03-01','0' union all
select '10005','03','2007-03-01','0'insert #t2(编号,部门,日期2,状态)
select '10003','02','2007-02-10','1'insert #t3(编号,部门,日期)
select '10001','01','2007-02-03' union all
select '10002','01','2007-02-10' union all
select '10003','02','2007-02-06' union all
select '10006','02','2007-03-02' union all
select '10001','03','2007-03-01' union all
select '10005','03','2007-02-22' union all
select '10005','03','2007-03-02'--求解过程1
select *
from #t3 t3
where exists(
select 1
from #t1 t1
where not exists--如果表1中有2个以上相同编号则以日期1最大的为条件
(select 1 from #t1 where 编号 = t1.编号 and 日期1 > t1.日期1)
and t3.编号 = t1.编号 and t3.部门 = t1.部门--表3中的编号和部门同时存在表1中
and not exists--表3中的编号和部门同时表2中不存在
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门)
)
union allselect *
from #t3 t3
where exists(
select 1
from #t1 t1
where not exists--如果表1中有2个以上相同编号则以日期1最大的为条件
(select 1 from #t1 where 编号 = t1.编号 and 日期1 > t1.日期1)
and t3.编号 = t1.编号 and t3.部门 = t1.部门--表3中的编号和部门同时存在表1中
and exists--表3中的编号和部门同时存在表2中
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门)
and not exists--当表1.max(日期1)>表2.max(日期2)才满足条件
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门 and 日期2 >= t1.日期1)
)
/*--测试结果
编号 部门 日期
----------- ---------- -------------------------
10002 01 2007-02-10 00:00:00.000
10006 02 2007-03-02 00:00:00.000
10001 03 2007-03-01 00:00:00.000
10005 03 2007-02-22 00:00:00.000
10005 03 2007-03-02 00:00:00.000(所影响的行数为 5 行)
*/-------------------------------------------------------------------------------求解过程2
select *
from #t3 t3
where exists(
select 1
from #t1 t1
where not exists--如果表1中有2个以上相同编号则以日期1最大的为条件
(select 1 from #t1 where 编号 = t1.编号 and 日期1 > t1.日期1)
and t3.编号 = t1.编号 and t3.部门 = t1.部门--表3中的编号和部门同时存在表1中
and not exists--表3中的编号和部门同时表2中不存在
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门)
)
or exists(
select 1
from #t1 t1
where not exists--如果表1中有2个以上相同编号则以日期1最大的为条件
(select 1 from #t1 where 编号 = t1.编号 and 日期1 > t1.日期1)
and t3.编号 = t1.编号 and t3.部门 = t1.部门--表3中的编号和部门同时存在表1中
and exists--表3中的编号和部门同时存在表2中
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门)
and not exists--当表1.max(日期1)>表2.max(日期2)才满足条件
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门 and 日期2 >= t1.日期1)
)
--删除测试环境
drop table #t1,#t2,#t3/*--测试结果
编号 部门 日期
----------- ---------- -----------------------------
10002 01 2007-02-10 00:00:00.000
10003 02 2007-02-06 00:00:00.000
10006 02 2007-03-02 00:00:00.000
10001 03 2007-03-01 00:00:00.000
10005 03 2007-02-22 00:00:00.000
10005 03 2007-03-02 00:00:00.000(所影响的行数为 6 行)
*/
解决方案 »
- 菜鸟求助~关于多表连接与group by的问题
- 如何写一个SQL
- 触发器问题???
- 请教在使用SMO分离数据库时不改变访问权限
- 请教这个约束怎么写?
- 急问:Sql Server的View中不支持Union,我该怎么办?
- 在sql中逻辑值和只能存储0与1的数据类型是什么?
- 返回datetime类型时只返回日期不返回后面的时间。。。
- 大家都推嵩oracle,对于一个200多人的企业,oracle8i 比sql server2000好多少?
- 在线 急 急 急 急 急 急
- I/O统计中的扫描计数和预读是什么意思?
- XPsp2,安装MSSQL2000个人版,快安装完时出现错误:创建一个或多个注册表项时出现错误。请参见 C:\WINXP\\\sqlstp.log 以了解详细情况。
where exists(A) or exists(B)与select * from t3 where exists(A)
union all
select * from t3 where exists(B) 是不是一个意思?另,业务逻辑:按部门汇总统计表3中不同的编号数(即不重复统计相同的编号),条件是:
一。
1》表3中的编号和部门同时存在表1中(表3.编号=表1.编号and 表3.部门=表1.部门),并且在表2中不存在,
2》如果表1中有2个以上记录满足条件1,则以日期1最大的为条件,如编号为10001的则以,编号=10001、部门=03为条件,故在表3中不统计编号=10001、部门=01的;二。或者
表3中的编号和部门同时存在表1和表2中,则当表1.max(日期1)>表2.max(日期2)才满足条件。如编号为10003,同时存存表1和表2中,但由于表1.max(日期1)<表2.max(日期2)(2007-02-01<2007-02-10)故在表3中不统计这条记录。 原帖见
http://community.csdn.net/Expert/topic/5373/5373716.xml?temp=.6307947
你的结果是一致的?Microsoft SQL Server 2000 - 8.00.194 (Intel X86)
Aug 6 2000 00:57:48
Copyright (c) 1988-2000 Microsoft Corporation
Personal Edition on Windows NT 5.1 (Build 2600: Service Pack 2)有问题吗?盗版的。操作系统是番茄花园XP。
where exists(A) or exists(B)与select * from t3 where exists(A)
union all
select * from t3 where exists(B) 条件exists(A) 与 exists(B)是互斥的,所以union all后不会出现重复的。
那么这两条语句结果就应该是一样的。
你把最后的>=变成<=可能会更好理解
select * from t3 where exists(A) or exists(B)
这两个exists可以合并成一个exists。
出错的原因应该是查询分析器在将它们合并的过程中优化错了。
--合并成一个exists就对了
--创建测试环境
create table #t1(编号 int,部门 varchar(10),日期1 datetime,状态 bit)
create table #t2(编号 int,部门 varchar(10),日期2 datetime,状态 bit)
create table #t3(编号 int,部门 varchar(10),日期 datetime)--插入测试数据
insert #t1(编号,部门,日期1,状态)
select '10001','01','2007-02-02','0' union all
select '10002','01','2007-02-06','0' union all
select '10003','02','2007-02-01','0' union all
select '10006','02','2007-03-02','0' union all
select '10001','03','2007-03-01','0' union all
select '10005','03','2007-03-01','0'insert #t2(编号,部门,日期2,状态)
select '10003','02','2007-02-10','1'insert #t3(编号,部门,日期)
select '10001','01','2007-02-03' union all
select '10002','01','2007-02-10' union all
select '10003','02','2007-02-06' union all
select '10006','02','2007-03-02' union all
select '10001','03','2007-03-01' union all
select '10005','03','2007-02-22' union all
select '10005','03','2007-03-02'--求解过程
select *
from #t3 t3
where exists(
select 1
from #t1 t1
where not exists--如果表1中有2个以上相同编号则以日期1最大的为条件
(select 1 from #t1 where 编号 = t1.编号 and 日期1 > t1.日期1)
and t3.编号 = t1.编号 and t3.部门 = t1.部门--表3中的编号和部门同时存在表1中
and (
not exists--表3中的编号和部门同时表2中不存在
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门)
or exists--表3中的编号和部门同时存在表2中
(select 1 from #t2 where 编号 = t1.编号 and 部门 = t1.部门)
and not exists--当表1.max(日期1)>表2.max(日期2)才满足条件
(select 1 from #t2 where 编号 = t1.编号
and 部门 = t1.部门 and t1.日期1 <= 日期2)
)
)
--删除测试环境
drop table #t1,#t2,#t3/*--测试结果
编号 部门 日期
----------- ---------- -------------------------
10002 01 2007-02-10 00:00:00.000
10006 02 2007-03-02 00:00:00.000
10001 03 2007-03-01 00:00:00.000
10005 03 2007-02-22 00:00:00.000
10005 03 2007-03-02 00:00:00.000(所影响的行数为 5 行)
*/
mygod 楼主的代码重写了以前的判断俄 这样也要修改阿 踹比尔一脚...
where exists(A) or exists(B)与select * from t3 where exists(A)
union all
select * from t3 where exists(B) 是不是一个意思?------------------
不是,跟
select * from t3 where exists(A)
union
select * from t3 where exists(B)
一个意思
有谁能够提供SQL SERVER 安装服务或支持?有偿服务.
13951709072
mengmou()mengmou() ( ) 信誉:100 Blog 2007-3-3 16:32:45 得分: 0
select * from t3
where exists(A) or exists(B)与select * from t3 where exists(A)
union all
select * from t3 where exists(B) 条件exists(A) 与 exists(B)是互斥的,所以union all后不会出现重复的。
那么这两条语句结果就应该是一样的。
Microsoft SQL Server 2000 - 8.00.194 (Intel X86)
Aug 6 2000 00:57:48
Copyright (c) 1988-2000 Microsoft Corporation
Personal Edition on Windows NT 5.1 (Build 2600: Service Pack 2)盗版的。还是 Personal sp2,操作系统是番茄花园XP。