--查询的逻辑执行过程,来自技术内幕 (8) SELECT (9) DISTINCT (11) <TOP_specification> <select_list> (1) FROM <left_table> (3) <join_type> JOIN <right_table> (2) ON <join_condition> (4) WHERE <where_condition> (5) GROUP BY <group_by_list> (6) WITH {CUBE | ROLLUP} (7) HAVING <having_condition> (10) ORDER BY <order_by_list>
人家问的是where a=b and c=d的执行顺序吧
select 1 where 1=1 or 1/0=1
and 前面为假 逻辑上不需要判断了。。 是从左往右
select 1 where 1=1 or 1/0=1 --1 select 1 where 1/0=1 or 1=1 --1求解
select 1 where 1=1 and 1/0=1 --遇到以零作除数错误。 select 1 where 1/0=1 and 1=1 --遇到以零作除数错误。
select 1 where 1/0=1 or 1=1 or 1/0=1 --1
select 1 where 1/0=1 or (1=1 and 1/0=1) --遇到以零作除数错误 select 1 where 'a'=1 or 1/0=1 --在将 varchar 值 'a' 转换成数据类型 int 时失败。 SELECT 1 WHERE 1=1 AND (1=1 OR 1/0=1) --1这样看来应该是这样的:同一级判断中有AND就全执行,只有OR就从左向右判断,出错了就判断下一个,如果全有错就报最左边的错误
不是很精确吧,如果后面有or还是会执行的 select 1 where 1/2=1 and 1=1 or 2=2----------- 1(1 行受影响)select 1 where 1/2=1 and 1=1 and 2=2 -----------(0 行受影响)
你这个不对,里面都没非法数据SELECT 1 WHERE 1/0=1 OR 1=1 AND 'A'=1 --遇到以零作除数错误。
--从左到右,不会抱错 set nocount on if(object_id('f_error') is not null) drop function f_error go create function dbo.f_error() returns bit as begin return 1/0 end go declare @t table(a int) insert into @t select 1 select * from @t where a=1 or dbo.f_error()=1 go --从左到右,不会抱错 if(object_id('f_test') is not null) drop function f_test go create function dbo.f_test() returns bit as begin return 1 end go declare @t table(a int) insert into @t select 1 select * from @t where dbo.f_test()=1 or a/0=1 set nocount off第一组测试代码
go --优化后从右到左,抱错,sql会找计算快的条件 if(object_id('f_test') is not null) drop function f_test go create function dbo.f_test() returns bit as begin return 1 end go declare @t table(a int) insert into @t select 1 select * from @t where dbo.f_test()=1 or 1/0=1 set nocount off go --优化后,不抱错,sql会找计算快的条件 if(object_id('f_test') is not null) drop function f_test go create function dbo.f_test() returns bit as begin return 1 end go declare @t table(a int) insert into @t select 1 select * from @t where dbo.f_test()=1 or 1=1 or 1/0=1 set nocount off第二组测试
CREATE FUNCTION TEST(@I INT) RETURNS INT BEGIN WHILE 1=1 BEGIN SET @I=@I+1 END RETURN 1 ENDCREATE FUNCTION TEST2(@I INT) RETURNS INT BEGIN RETURN 1 END SELECT 1 WHERE 1/0=1 OR DBO.TEST(1)=1 OR 1=1 OR DBO.TEST(1)=1 --1SELECT 1 WHERE 1/0=1 OR DBO.TEST(1)=1 OR DBO.TEST(1)=1 OR DBO.TEST(1)=1 --遇到以零作除数错误SELECT 1 WHERE DBO.TEST(1)=1 OR DBO.TEST(1)=1 OR DBO.TEST(1)=1 --死循环DROP FUNCTION TEST DROP FUNCTION TEST2根据这个结果来看SQL会在调用函数前对直接进行的运算优先从左到右运行,之后应该是从左到右执行函数
SELECT 1 WHERE 1/0=1 OR 1=1 AND 'A'=1 --遇到以零作除数错误。那是因为and的优先级高于or,所以1/0要被计算
SELECT 1 WHERE 1/0=1 OR 1=1 AND 'A'='A' --1 SELECT 1 WHERE 1/0=1 OR 1=1 AND 'A'=1 --遇到以零作除数错误 那AND和OR在同一级的话应该是相当于在AND的左右加个一个括号吧
SELECT 1 WHERE DBO.TEST3(1)=1 OR DBO.TEST(1)=1 AND DBO.TEST2(1)=1 --遇到以零作除数错误 SELECT 1 WHERE DBO.TEST(1)=1 OR DBO.TEST2(1)=1 AND DBO.TEST3(1)=1 --死循环 SELECT 1 WHERE DBO.TEST(1)=1 OR DBO.TEST2(1)=1 AND DBO.TEST2(1)=1 --死循环 SELECT 1 WHERE DBO.TEST2(1)=1 OR DBO.TEST(1)=1 AND DBO.TEST3(1)=1 --1这样看来FUNCTION 之间的AND不会起作用,会依次从左向右执行
这个应该算FUNCTION与直接运算在一起吧,会优先运行后者 SELECT 1 WHERE DBO.TEST(1)=1 OR 1=1 OR DBO.TEST(1)=1 --1
sql会优先计算常量表达式..我现在想找出来会干扰索引的条件组合,而不是lz本身的这个问题
CREATE TABLE GUGUDA_TEST( COL1 INT PRIMARY KEY, COL2 INT ) INSERT INTO GUGUDA_TEST SELECT 1,2 UNION ALL SELECT 3,4SELECT COL1,COL2 FROM GUGUDA_TEST WHERE DBO.TEST(COL2)=1 OR DBO.TEST2(COL1)=1 --死循环建了个PRIMARY KEY,看来不起作用,还是会按顺序执行,TEST2是正常的,TEST1是死循环
select @@VERSIONcreate table tb( item_local_code char(5), sub_del_flag int, sub_para varchar(10), constraint PK_t primary key(sub_para,item_local_code) ) insert tb select '03004',1,'2003-1-1' union all select '03005',1,'2003a1-1' go--查询语句 select * from ( select * from tb where item_local_code='03004' and sub_del_flag<>0 and isdate(sub_para)=1 ) A where datediff(day,sub_para,getdate())>29 go--删除测试 drop table tb
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Microsoft SQL Server 2000 - 8.00.2039 (Intel X86) May 3 2005 23:18:38 Copyright (c) 1988-2003 Microsoft Corporation Personal Edition on Windows NT 5.2 (Build 3790: Service Pack 2) (所影响的行数为 2 行)item_local_code sub_del_flag sub_para --------------- ------------ ---------- 03004 1 2003-1-1服务器: 消息 241,级别 16,状态 1,行 3 从字符串转换为 datetime 时发生语法错误。
SELECT 1 WHERE 1=1 AND (1=1 OR 1/0=1) 1 select 1 where 1/0=1 or (1=1 and 1/0=1) 遇到被零除错误。 select 1 where 'a'=1 or 1/0=1 将 varchar 值 'a' 转换为数据类型为 int 的列时发生语法错误。
not and or 执行先后。。
如果where前面的为false不成立。后面的and就不会执行了。。
我用的SQL2000;我认为如果只有and(取交集)的话应该 从左到右判断正误的,如果前面的错了后面不会判断;如果条件里面有or(并集)的话,应该还是从左到右 但是这个的 左面部分或者右面部分 作为独立单元给出(0/1)就像 如果or左面部分是1那么就不会判断右面部分,除非后面还有and 也就是and or 同时出现时就不一定不 判断后面的一部分
哇!顶得这么高了呀? 实在是太谢谢各位关注了.原来我也是认为它也会像其它语言一样,从左到右,如果第一个条件不满足就不执行了,但有时发现好像不是那样.所以,特来问一下,像'and'的之间的表达式复杂度有时候会有很大差别,性能当然也就受影响.原来还真不简单,嘿嘿~~~ 好好向你们学习~ thank you again~ ^_^~
(8) SELECT (9) DISTINCT (11) <TOP_specification> <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH {CUBE | ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY <order_by_list>
是从左往右
select 1 where 1=1 or 1/0=1
--1
select 1 where 1/0=1 or 1=1
--1求解
select 1 where 1=1 and 1/0=1
--遇到以零作除数错误。
select 1 where 1/0=1 and 1=1
--遇到以零作除数错误。
--1
select 1 where 1/0=1 or (1=1 and 1/0=1)
--遇到以零作除数错误
select 1 where 'a'=1 or 1/0=1
--在将 varchar 值 'a' 转换成数据类型 int 时失败。
SELECT 1 WHERE 1=1 AND (1=1 OR 1/0=1)
--1这样看来应该是这样的:同一级判断中有AND就全执行,只有OR就从左向右判断,出错了就判断下一个,如果全有错就报最左边的错误
select 1 where 1/2=1 and 1=1 or 2=2-----------
1(1 行受影响)select 1 where 1/2=1 and 1=1 and 2=2
-----------(0 行受影响)
--遇到以零作除数错误。
set nocount on
if(object_id('f_error') is not null)
drop function f_error
go
create function dbo.f_error()
returns bit
as
begin
return 1/0
end
go
declare @t table(a int)
insert into @t select 1
select * from @t where a=1 or dbo.f_error()=1
go
--从左到右,不会抱错
if(object_id('f_test') is not null)
drop function f_test
go
create function dbo.f_test()
returns bit
as
begin
return 1
end
go
declare @t table(a int)
insert into @t select 1
select * from @t where dbo.f_test()=1 or a/0=1
set nocount off第一组测试代码
--优化后从右到左,抱错,sql会找计算快的条件
if(object_id('f_test') is not null)
drop function f_test
go
create function dbo.f_test()
returns bit
as
begin
return 1
end
go
declare @t table(a int)
insert into @t select 1
select * from @t where dbo.f_test()=1 or 1/0=1
set nocount off
go
--优化后,不抱错,sql会找计算快的条件
if(object_id('f_test') is not null)
drop function f_test
go
create function dbo.f_test()
returns bit
as
begin
return 1
end
go
declare @t table(a int)
insert into @t select 1
select * from @t where dbo.f_test()=1 or 1=1 or 1/0=1
set nocount off第二组测试
RETURNS INT
BEGIN
WHILE 1=1
BEGIN
SET @I=@I+1
END
RETURN 1
ENDCREATE FUNCTION TEST2(@I INT)
RETURNS INT
BEGIN
RETURN 1
END
SELECT 1 WHERE 1/0=1 OR DBO.TEST(1)=1 OR 1=1 OR DBO.TEST(1)=1
--1SELECT 1 WHERE 1/0=1 OR DBO.TEST(1)=1 OR DBO.TEST(1)=1 OR DBO.TEST(1)=1
--遇到以零作除数错误SELECT 1 WHERE DBO.TEST(1)=1 OR DBO.TEST(1)=1 OR DBO.TEST(1)=1
--死循环DROP FUNCTION TEST
DROP FUNCTION TEST2根据这个结果来看SQL会在调用函数前对直接进行的运算优先从左到右运行,之后应该是从左到右执行函数
--遇到以零作除数错误。那是因为and的优先级高于or,所以1/0要被计算
SELECT 1 WHERE 1/0=1 OR 1=1 AND 'A'='A'
--1
SELECT 1 WHERE 1/0=1 OR 1=1 AND 'A'=1
--遇到以零作除数错误
那AND和OR在同一级的话应该是相当于在AND的左右加个一个括号吧
SELECT 1 WHERE DBO.TEST3(1)=1 OR DBO.TEST(1)=1 AND DBO.TEST2(1)=1
--遇到以零作除数错误
SELECT 1 WHERE DBO.TEST(1)=1 OR DBO.TEST2(1)=1 AND DBO.TEST3(1)=1
--死循环
SELECT 1 WHERE DBO.TEST(1)=1 OR DBO.TEST2(1)=1 AND DBO.TEST2(1)=1
--死循环
SELECT 1 WHERE DBO.TEST2(1)=1 OR DBO.TEST(1)=1 AND DBO.TEST3(1)=1
--1这样看来FUNCTION 之间的AND不会起作用,会依次从左向右执行
SELECT 1 FROM TB WHERE FUNCTION(COL1)=1 OR FUNCTION(COL2)=1
如果COL2是索引列会优先执行?
如果COL2是索引列会优先执行但现在看了一下貌似不会了
搜索了一下,zj的这篇文章
http://blog.csdn.net/zjcxc/archive/2004/09/22/112902.aspx在sql2005之下已经不适用了
SELECT 1 WHERE DBO.TEST(1)=1 OR 1=1 OR DBO.TEST(1)=1
--1
CREATE TABLE GUGUDA_TEST(
COL1 INT PRIMARY KEY,
COL2 INT
)
INSERT INTO GUGUDA_TEST
SELECT 1,2 UNION ALL
SELECT 3,4SELECT COL1,COL2 FROM GUGUDA_TEST WHERE DBO.TEST(COL2)=1 OR DBO.TEST2(COL1)=1
--死循环建了个PRIMARY KEY,看来不起作用,还是会按顺序执行,TEST2是正常的,TEST1是死循环
item_local_code char(5),
sub_del_flag int,
sub_para varchar(10),
constraint PK_t primary key(sub_para,item_local_code)
)
insert tb select '03004',1,'2003-1-1'
union all select '03005',1,'2003a1-1'
go--查询语句
select * from (
select * from tb
where item_local_code='03004'
and sub_del_flag<>0
and isdate(sub_para)=1
) A where datediff(day,sub_para,getdate())>29
go--删除测试
drop table tb
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2000 - 8.00.2039 (Intel X86)
May 3 2005 23:18:38
Copyright (c) 1988-2003 Microsoft Corporation
Personal Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
(所影响的行数为 2 行)item_local_code sub_del_flag sub_para
--------------- ------------ ----------
03004 1 2003-1-1服务器: 消息 241,级别 16,状态 1,行 3
从字符串转换为 datetime 时发生语法错误。
你换你的类型为char 或varchar时,注意索引覆盖
http://topic.csdn.net/u/20080728/17/0cdb96bc-9817-4570-8039-fcba3b156be4.html
今天在公交上老远看见FC走近一看是 FC - 非常发型屋
如果or的话,找到以第一个为真的条件后就不再计算
如果and的话,找到以第一个为假的条件后就不再计算
1 & 1=1
1 & 0=0
0 & 1=0
0 & 0=0其中Where ...and...
"and" 代表逻辑与and前面的参数逻辑值为0(假) 那么where 条件的逻辑值也为0(假) where前面的sql语句不会执行
如果没有优化的情况下的确是这样,fc是对的,这个不能想当然.反正sql2000和sql2005的优化策略有所不同
SELECT 1 WHERE 1=1 AND (1=1 OR 1/0=1)
1
select 1 where 1/0=1 or (1=1 and 1/0=1)
遇到被零除错误。
select 1 where 'a'=1 or 1/0=1
将 varchar 值 'a' 转换为数据类型为 int 的列时发生语法错误。
实在是太谢谢各位关注了.原来我也是认为它也会像其它语言一样,从左到右,如果第一个条件不满足就不执行了,但有时发现好像不是那样.所以,特来问一下,像'and'的之间的表达式复杂度有时候会有很大差别,性能当然也就受影响.原来还真不简单,嘿嘿~~~
好好向你们学习~
thank you again~
^_^~
如果and的话,找到以第一个为假的条件后就不再计算
System.out.println("顶");
}