and a2.ftype=3是必须的条件,其实相当于a2和a1内连接
select a1.fname,a2.fvalue
from t2 a1
left join t2 a2 on a1.fid=a2.pid
where a1.ftype=2 and a2.ftype=3and a2.ftype=3非必要条件,可以查询出不满足a1.fid=a2.pid and a2.ftype=3条件的记录。
select a1.fname,isnull(a2.fvalue,'') as fvalue
from t2 a1
left join t2 a2 on a1.fid=a2.pid and a2.ftype=3
where a1.ftype=2
select a1.fname,a2.fvalue
from t2 a1
left join t2 a2 on a1.fid=a2.pid
where a1.ftype=2 and a2.ftype=3and a2.ftype=3非必要条件,可以查询出不满足a1.fid=a2.pid and a2.ftype=3条件的记录。
select a1.fname,isnull(a2.fvalue,'') as fvalue
from t2 a1
left join t2 a2 on a1.fid=a2.pid and a2.ftype=3
where a1.ftype=2
解决方案 »
- 每个客户的销售前三个产品
- SQL中TYPE是啥意思
- 问个简单问题 就不给多少分了
- 老问题:两台数据库同步,看了很多试了很多没有成功过
- ◆◆◆看看这个语句,感觉执行的效率不高,怎么优化呢?◆◆◆在线等待...
- 把 foxpro dbf文件导入sql2000发生错误
- 求救,怎么把sql2000 紧急状态下的数据库中,把里面的表导出来
- 请问sql2000与2005在decimal上的返回码问题
- 问个关于数据查询的问题!!!
- SQLServer定时同步数据到Oracle中,求各位大神帮忙解决,谢谢!!!
- 大牛快来丫,郁闷了一天了:sql server 2008 r2 windows身份认证和SA两种登录模式被禁用
- 在一张表中查询出百家姓排行情况的SQL要怎么写呢?从Group By 着手?
而外连接,如左连接,左连接分为左输入和右输入,SQL查询将两个输入根据ON后面的条件过滤出一个积,然后再把左输入存在的而右输入不存在的加入进来,然后再执行WHERE条件过滤
我的描述可能不是完全官方标准,但是,接近了,大体意思就是这样,SQL查询的逻辑处理顺序。
因此,从上面我们可以推出,a2.ftype=3放在WHERE上,过滤的是最终的结果,而放到左连接只取到限制右输入的作用
on a1.fid=a2.pid where a1.ftype=2 and a2.ftype=3 过滤最终结果。
on a1.fid=a2.pid and a2.ftype=3 where a1.ftype=2 限制又输入。
from (select fid,fname from t2 where ftype=2) a1
left join (select pid,fvalue from t2 where ftype=3) a2
on a1.fid=a2.pid这样子是可以得到3条记录,也是我所需要的,而且这个我也能理解,只是有些麻烦
from t2 a1
left join t2 a2 on a1.fid=a2.pid
where a1.ftype=2 and a2.ftype=3它不是先做筛选,然后在两个临时表中做Left Join吗?
所以我想使用以下写法,
select a1.fname,isnull(a2.fvalue,'') as fvalue
from t2 a1,t2 a2
where a1.ftype=2 and a2.ftype=3 and a1.fid*=a2.pid似乎join可以完全不用
on 是对联合多张表的条件关联。on 的在时间顺序要优先于 where 。
select a1.fname,isnull(a2.fvalue,'') as fvalue
from t2 a1
left join t2 a2 on a1.fid=a2.pid and a2.ftype=3
where a1.ftype=2
我总觉得这跟我的思维有些冲突
以下步骤显示 SELECT 语句的处理顺序
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE 或 WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP
*= 和 =* 外部联接运算符
使用 FROM 子句的 JOIN 语法。
-------------------------------------
我问你,你判断结果对不对的时候是不是先筛选后比对(Join)
JOIN 的时候,会先用ON过滤不合适的,然后再JOIN,最后再WHERE,这是正常的处理顺序,即逻辑上的处理顺序,但是,SQL查询优化在内连接的时候,会提前把WHERE的条件带进去过滤,因为这样的结果一样,而且会更有效率,而是物理处理上真正的处理顺序
但是,如果是外连接,提前把WHERE带入过滤得出的结果是不对的,所以左外连接的时候,不会提前把右输入的过滤条件带进去,只会在JOIN后进行筛选,然后,左输入存在而右输入不存在的情况,会把左输入的数据加上右输入的全部设置为NULL加到JOIN后的积,这时在进行WHERE的筛选,不符合条件及涉及NULL的判断全部是FALSE,全部会被过滤掉
ON后面的条件是
WHERE后面的条件不一定是
其实所有的 join 你都应该看成遍历游标的双层循环:
select a1.fname,a2.fvalue
from t2 a1
left join t2 a2 on a1.fid=a2.pid
where a1.ftype=2 and a2.ftype=3
外层游标 SELECT * FROM t2 a1 WHERE a1.ftype=2,循环:
内存游标 SELECT * FROM t2 a2 WHERE a1.fid=a2.pid,由于是左连接,不加条件 a2.ftype
如果 a2 为空,输出有 a1 无 a2 的记录;
如果 a2.ftype=3,输出 a1、a2 都有的记录;
如果 a2.ftype<>3,不输出记录。
select a1.fname,isnull(a2.fvalue,'') as fvalue
from t2 a1
left join t2 a2 on a1.fid=a2.pid and a2.ftype=3
where a1.ftype=2
外层游标一样是 SELECT * FROM t2 a1 WHERE a1.ftype=2,循环:
内存游标 SELECT * FROM t2 a2 WHERE a1.fid=a2.pid and a2.ftype=3,由于是on条件,可以加在这里
如果对应 a2.pid 本来就没记录,内游标为空,输出有 a1 无 a2 的记录;
如果对应 a2.pid 的记录 a2.ftype=3,一样输出 a1、a2 都有的记录;
如果对应 a2.pid 的记录全部 a2.ftype<>3,内游标为空,输出有 a1 无 a2 的记录。
where是对最后的结果集做筛选的
不过你们解释的是写出来的语句逻辑对不对不过,以我的思维(我是说用肉眼判断)是
1.select * from t2 a1 where a1.ftype=2
2.select * from t2 a2 where a2.ftype=3
3.用肉眼一一比对,它实际上是双层循环我觉得大家应该都是这样做的吧,这里a1.ftype=2与a2.ftype=3地位是相等的,
结果生成语句的时候要把a2.ftype=3放在on子句后,原因是on先于where执行
可是我们分析问题时肯定先where后join
-----------------------------------------
我是说我的逻辑与Sql语句有些不同select a1.fname,isnull(a2.fvalue,'') as fvalue
from (select fid,fname from t2 where ftype=2) a1
left join (select pid,fvalue from t2 where ftype=3) a2
on a1.fid=a2.pid
与
select a1.fname,isnull(a2.fvalue,'') as fvalue
from t2 a1
left join t2 a2 on a1.fid=a2.pid and a2.ftype=3
where a1.ftype=2
有没有不同,我看它们的执行计划似乎是一样的
SET SHOWPLAN_ALL ON;
go