WEB开发网
开发学院数据库MSSQL Server SQL语句分析:ON与WHERE的比较_简单嵌套查询与非嵌... 阅读

SQL语句分析:ON与WHERE的比较_简单嵌套查询与非嵌套查询的比较

 2010-01-07 00:00:00 来源:WEB开发网   
核心提示: 在这里,把a.NAME != 'aa' 放在where后面以及放在c的on后面,SQL语句分析:ON与WHERE的比较_简单嵌套查询与非嵌套查询的比较(4),查询出来的结果:发现sql语句b比sql语句a的结果多了一行记录,这里c.id和c.name为NULL,当前的例子,不存在

在这里,把a.NAME != 'aa' 放在where后面以及放在c的on后面,查询出来的结果:

SQL语句分析:ON与WHERE的比较_简单嵌套查询与非嵌套查询的比较

发现sql语句b比sql语句a的结果多了一行记录,这里c.id和c.name为NULL,到底为什么呢?再做一个实验:

--c.

SELECT
*
FROM @a a
LEFT JOIN @b b ON a.id = b.id AND
a.[NAME] != 'aa'
LEFT JOIN @c c ON b.id = c.id

这次把条件放到b后面了,看b和c的查询结果的对比图:

SQL语句分析:ON与WHERE的比较_简单嵌套查询与非嵌套查询的比较

发现不仅是c.id和c.name,连b.id和b.name为NULL,这是为什么呢?

从语义上来分析sql语句b中的 “LEFT JOIN @c c ON b.id = c.id AND a.NAME != 'aa'”,表c和x(x为表a和表b连结后的中间结果)连结后的中间结果x1中,a.NAME不等于'aa'的行是不存在的,因此c.id和c.name为NULL。

从语义上来分析sql语句c中的 “LEFT JOIN @b b ON b.id = c.id AND a.NAME != 'aa'”,表b和表a连结后的中间结果x2中,a.NAME不等于'aa'的行是不存在的,因此b.id和b.name为NULL。又因为“LEFT JOIN @c c ON b.id = c.id”,b.id为NULL,所以c.id和c.name为NULL。

inner join和left join不一样,inner join左边或右边的结果为空,该行记录就不显示了。而left join会以左边的表为保留表,就算右边的结果为空,该行仍然显示。

于是得出的结论是:条件放在on与放在where后面的作用是不一样的。on对中间结果进行筛选(个人更倾向于中间运算),再由where对最终结果进行筛选。

PS3:下面是Left Join on+where的执行过程(附上songmc给我的文档的精华部分)

sql:

SELECT * 
FROM a 
LEFT JOIN b ON a.id = b.id AND b.Name != 'ff'
WHERE a.NAME != 'aa' 

步骤1:返回笛卡尔积(SELECT * FROM @a a CROSS JOIN @b b)

步骤2:应用ON筛选器(当前的条件为a.id = b.id AND b.Name != 'ff')

步骤3:添加外部行

这一步只对OUTER JOIN起作用,如果是LEFT JOIN会以左边的表为保留表,如果是RIGHT JOIN会以右边的表为保留表。所谓外部行是指,保留表中的行。即使第二步的ON过滤掉了一些行,在这一步,会根据保留表添加第二步过滤掉的行。当前的例子,不存在这种情况。

步骤4.应用WHERE筛选器(当前是Name != ‘aa’)过滤前三步所生成虚拟表的数据。

上一页  1 2 3 4 

Tags:SQL 语句 分析

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接