补充一下,原始SQL如下: select t.xn, t.xq_id , t.xh, t.itemname, t.itemcount, t.sfbzcount, t.hjje, t.hjrq, t.bz, t.startyear, t.bstartyear, t.bxh, t.bitemname from (select a.xn, a.xq_id , a.xh, a.itemname, a.itemcount, a.sfbzcount, a.hjje, a.hjrq, a.bz, a.startyear, b.xh bxh, b.startyear bstartyear, b.itemname bitemname from student2010_temp a, T_XJ_STUD_JF_Outer b where a.startyear *= b.startyear and a.xh *= b.xh and a.itemname *= b.itemname) t where (t.bstartyear is null) or (t.bxh is null) or (t.bitemname is null)容易看的版本: select t.xn, t.xq_id, t.xh, t.itemname, t.itemcount, t.sfbzcount, t.hjje, t.hjrq, t.bz, t.startyear, t.bstartyear, t.bxh, t.bitemname from (select a.xn, a.xq_id, a.xh, a.itemname, a.itemcount, a.sfbzcount, a.hjje, a.hjrq, a.bz, a.startyear, b.xh bxh, b.startyear bstartyear, b.itemname bitemname from student2010_temp a, T_XJ_STUD_JF_Outer b where a.startyear * = b.startyear and a.xh * = b.xh and a.itemname * = b.itemname) t where (t.bstartyear is null) or (t.bxh is null) or (t.bitemname is null)
这个很正常啊,有什么问题?你用ansi标准 *=模式写了一个左连, 然后用子查询将它包起来。在 *= 模式左连接中,where 条件里 只涉及左输入的的部分 是过滤条件, 只要涉及到右输入的部分都是关联条件,你加了 where t.bstaruear is null后, t.bstaryear来源于子查询左连接的右输入, 当然会理解为连接条件了, 不合连接要求,自然输出是null.你自认为左连后 包了一层查询再来过滤的, 实际上不一定是你想的那样, 因为你的子查询并未涉及到一些变更,所以优化器会去掉你的子查询的。就比如 select * from (select * from tb where name='aa' ) a where id=1这条语句会被优化为 select * from tb where id=1 and name='aa' 一样。所以推荐的做法是sql92标准 a left join b on 连接条件 where 过滤条件
你检查一下数据看,应该是本来子查询就有好多的NULL.你只看到了第一条,但并不是只有第一条. 在不加后面条件的前提下,在语句后面加上一个 order by xh 就知道了. 其实,错误是你的数据,你的T_XJ_STUD_JF_Outer 表中有学号为 NULL 的数据,觉得这条记录是错的,这条记录与其他所有学号进行左连接,得到了许多不该有的数据行.
select t.xn, t.xq_id , t.xh, t.itemname, t.itemcount, t.sfbzcount, t.hjje, t.hjrq, t.bz, t.startyear,
t.bstartyear, t.bxh, t.bitemname from
(select a.xn, a.xq_id , a.xh, a.itemname, a.itemcount, a.sfbzcount, a.hjje, a.hjrq, a.bz, a.startyear,
b.xh bxh, b.startyear bstartyear, b.itemname bitemname
from student2010_temp a, T_XJ_STUD_JF_Outer b
where a.startyear *= b.startyear and a.xh *= b.xh and a.itemname *= b.itemname) t
where (t.bstartyear is null) or (t.bxh is null) or (t.bitemname is null)容易看的版本:
select t.xn,
t.xq_id,
t.xh,
t.itemname,
t.itemcount,
t.sfbzcount,
t.hjje,
t.hjrq,
t.bz,
t.startyear,
t.bstartyear,
t.bxh,
t.bitemname
from (select a.xn,
a.xq_id,
a.xh,
a.itemname,
a.itemcount,
a.sfbzcount,
a.hjje,
a.hjrq,
a.bz,
a.startyear,
b.xh bxh,
b.startyear bstartyear,
b.itemname bitemname
from student2010_temp a, T_XJ_STUD_JF_Outer b
where a.startyear * = b.startyear
and a.xh * = b.xh
and a.itemname * = b.itemname) t
where (t.bstartyear is null)
or (t.bxh is null)
or (t.bitemname is null)
有问题呀,您仔细看下,我没加筛选NULL之前,是能搜索出来有NULL的值,第一条就是
我加了条件,我是期盼可以只搜索出来一条,就是第一条
但是加了之后,记录都一样,就最后三个字段全都成了NULL
我建了两个表测试,发现没问题,不知道是不是数据有点多的缘故,大约有7w条数据,这个sql执行很快,但是结果却不正确
因为你加了 where is null 所以只查null值啊?有问题么?
按说加了条件,应该就出来我删掉的那条记录,就是第一条记录。我本来是想select出来T_XJ_STUD_JF_Outer里面不存在,而student2010_temp里面存在的记录,然后用一条insert语句来执行,这样速度快,但是发现一加限定条件结果就不正确。小弟临时接触mssql,平常都是用的ORACLE,不知道是不是mssql的bug或者是我的语法不正确。盼复
我都试了,只加一个条件都会变成NULL
只有没有where条件的情况下才不会变成NULL
在不加后面条件的前提下,在语句后面加上一个 order by xh 就知道了.
其实,错误是你的数据,你的T_XJ_STUD_JF_Outer 表中有学号为 NULL 的数据,觉得这条记录是错的,这条记录与其他所有学号进行左连接,得到了许多不该有的数据行.
既然你选了 where is null 那结果肯定是null的啊
里面我只删除了一条记录
应该是只出来我删掉的那条记录才对
我先按照上面那个大哥的建议用SQL92标准试试~
那么不管bstaryear是否null, 左输入都会有输出,
而当b.staryear值本身是null时, 右输出输出字段本身, 即null
并当b.staryear值本身不是null时,因为不符合连接条件,那钢么右输出还是null这才是产生null的原因。
已经OK了,谢谢啊,超级感谢
也谢谢路上的各位热心的GGJJ~OK,结贴~