疑难杂症:and和or
问题:一张表tj_lmj_sp_1有如下字段:(spid varchar(255),cpid varchar(30),acct_item_type_id decimal(9,0),acct_item_type_name varchar(200),charge decimal(16,5))
现要求:排除所有spid为0或为null的记录,并且排除所有cpid为0或为null的记录,然后求sum(charge)。
根据此要求,写出的sql如下:
sql1:
select sum(charge) from
(select *
from (select * from tj_lmj_sp_1 where cpid is not null and cpid <> 0) a
where spid is not null and spid <> 0
) b
另外换种写法,结果正确:
sql2:
select spid,cpid,acct_item_type_id,acct_item_type_name,sum(charge)
from tj_lmj_sp_1
where (spid is not null and spid <> 0) --排除所有spid为0或为null的
and (cpid is not null and cpid <> 0) --排除所有cpid为0或为null的
group by spid,cpid,acct_item_type_id,acct_item_type_name
再换种写法,结果错误:
sql3:
select spid,cpid,acct_item_type_id,acct_item_type_name,sum(charge)
from tj_lmj_sp_1
where (spid is not null or spid <> 0) --排除所有spid为0或为null的
and (cpid is not null or cpid <> 0) --排除所有cpid为0或为null的
group by spid,cpid,acct_item_type_id,acct_item_type_name
sql3统计的结果中还包含有sqid=0或者是cpid=0的记录,sql3错在哪里呢?
从逻辑上看,感觉sql3是正确的,sql2是错误的,对sql2做如下变形:
select count(*) from tj_lmj_sp_1 where spid is not null and spid <> 0
select count(*) from tj_lmj_sp_1 where cpid is not null and cpid <> 0
这两句sql统计的结果一定是0,但sql2的最终结果就是正确的,sql3的结果就是错误的,这是为何?
如果把sql3 where条件里面的and换成or也是错误的,即:
select spid,cpid,acct_item_type_id,acct_item_type_name,sum(charge)
from tj_lmj_sp_1
where (spid is not null or spid <> 0) --排除所有spid为0或为null的
or (cpid is not null or cpid <> 0) --排除所有cpid为0或为null的
group by spid,cpid,acct_item_type_id,acct_item_type_name
[解决办法]