SQL联接查询

联接查询

Join表操作符对两个输入表进行了操作。联结有三种基本类型:交叉连接,内连接,外链接。这三种连接的区别是它们采用的逻辑查询处理步骤各部相同,每种连接都有一套不同的步骤。交叉连接只有一个步骤—笛卡尔积;内连接有两个步骤—笛卡尔积,过滤;外链接有三个步骤—笛卡尔积,过滤,添加外部行。

交叉连接

交叉联接是一种最简单的联接,交叉联接只实现一个笛卡尔积即可。这一步就是对两张表进行操作,把它们联接起来,生成两者的笛卡尔积。也就是将一个输入表的每行和另一张表的每行进行匹配。如果一张表有n行,另一张表有m行,将得到m * n行。

ANSI  SQL-92:Cross Join

ANSI  SQL-89:在两张表间放置一个逗号

 

内连接

内连接要应用两个逻辑查询处理步骤:它首先像交叉联接一样,对两个输入表进行笛卡尔积运算:然后根据用户指定的谓词对结果进行过滤。和交叉联接一样,内联接也有两种标准语法。

ANSI  SQL-92:Inner Join 或者 Join(由于内连接是默认的联接方式,所以也可以只写Join)

ANSI  SQL-89:在两张表间放置一个逗号,在查询的where子句中写过滤条件。

扫描二维码关注公众号,回复: 2448106 查看本文章

强烈推荐使用Inner Join,因为假如你忘记写过滤条件(on),执行时SQL会报错。而如果使用SQL-89语法,则不会报错。那么这个内连接就变成交叉连接了! 而且实际开发中SQL语句会非常的复杂,写错的概率就很大了。

 

组合连接

有时候过滤条件不止一个,这时候就要用and来连接多个条件,这就叫做组合连接。例如:Table2表中定义了一个外键(col1和col2),引用了Table1表的col1和col2列,现在要写一个根据主外键关系来连接两个表的查询语句。该条件如下:

FROM TABLE1 AS T1

JOIN TABLE2 AS T2

ON T1.col1 = T2.col1 AND T1.col2 = T2.col2

 

不等连接

如果连接条件包含等号运算符,那么这样的连接叫做等值连接(equi join)。如果连接条件包含除等号以外的其他运算符,那么这样的连接叫做不等连接(non-equi join)。

 

多表连接

一个联接表运算符只对两个表进行操作,而一条查询语句可以包含多个联接。通常,当FROM子句中包含多个表运算符时,表运算符在逻辑上是按从左到右的顺序处理的。也就是说,第一个表运算符的结果将作为第二个表运算符的输入,第二个表运算符的结果将作为第三个运算符左边的输入,以此类推。

 

外连接

外连接会应用内连接所应用的两个逻辑处理步骤(笛卡尔积和On过滤),此外还多一个外连接特有的第三步:添加外部行。

在外联接中,耍把一个表标记为“保留的”表,可以在表名之间使用关键字LEFT OUT JOIN、RIGHT OUTER JOIN ,以及 FULL OUTER JOIN,其中 OUTER 失键字是可选的。 LEFT关键字表示左边表的行是保留的关键字表示右边表的行是保留的,而FULL 关键字则表示左右两边表的行都是保留的。外联接的第三个逻辑杏询处理步骤就是要识别保留表中按照ON条件在另一个表找不到与之匹配的那些行,再把这些行添加到联接 的前两个步骤生成的结果表中:对于来自联接的非保留表的那些列,追加的外部行中的 这些列则用NULL作为占位符。

外连接常见问题

1.对外联接中非保留表的列进行过滤

当检查涉及外联接的代码时,查找逻辑错误时,应该检查的一个地方就是WHERE子句。如果WHERE子句的条件是以<列><运算符><值>的形式引用了联接中的非保留表的列。这通常就是存在错误的一个标志。因为外联接得到的外部行中来自非保留字的列值均为NULL,而NULL <运算符><值>这种格式只会得到UNKNOWN(除非使用IS NULL运算符,显示查找NULL值)。这种结果相当于抵消了外联接的作用。

2.在多表连接中使用外连接

在From子句中运行的表运算符并不适用与“同时操作”,表运算符逻辑上是从左到右计算的。对外联接的处理顺序的调整,可能会影响到输出结果,所以不能随便改变它们的顺序。

例如:假设现在要写一条多表联接查询语句,先对两张表进行外联接,再和第三种表进行内连接。如果在内连接ON子句中的条件是对来自外联接非保留表的列和第三张表的列进行比较,那么所有的外部行都会被过滤掉。

记住,对于外部行,其来自非保留表的列值为NULL;把NULL和任何值进行比较,得到的都是UNKNOWN;UNKNOWN都会被ON过滤掉。

那么我们如何避免这种情况呢?我们可以采用调换顺序的方式来解决这个问题,或者采用()来让内连接先执行,最后在外联接。

2.随外联接一起使用COUNT聚合函数

另一个常见的逻辑错误是与外联接一起使用COUNT聚合函数有关。当对外连接的结果进行分组,再使用COUNT(*)聚合函数时,聚合操作会把内部行和外部行都计算在内,因为它不计算行数,而不管行的内容。但通常是不希望把外部行也纳入计数的考虑范围之内。

为了解决这一个问题,应该用COUNT(<COLUMN>)来代替COUNT(*),并从联接的非保留表中选择一个列。这样一来   COUNT就会忽略外部行,因为这些行在计数列上的值为NULL。记住要选择只有在外部行中列值为NULL的列。

猜你喜欢

转载自blog.csdn.net/xc917563264/article/details/81100041