1.连接查询
如:SELECT * FROM t1, t2;
上述FROM语句将t1表,t2表连接。
假设t1表含n条记录,t2表含m条记录,则t1, t2得到的表将包含n*m条记录。
我们以一个混合连接,过滤的查询分析语句执行过程。
如:SELECT * FROM t1, t2 WHERE t1.m1 > 1 AND t1.m1 = t2.m2 AND t2.n2 < ‘d’;
(1).针对FROM子句得到结果集1。
(2).对结果集1中每行执行过滤条件,得到结果集2。
(3).对结果集2执行SELECT得到最终结果集。
上述是从执行效果角度解释执行逻辑。实际执行中为了效率优化的考量,会视t1为驱动表,视t2为被驱动表。
先结合WHERE子句对驱动表执行过滤,再针对过滤后表中每条记录与被驱动表结合执行其他过滤条件以得到最终结果集。
2.内连接和外连接
执行连接查询时,如果驱动表中某一行执行连接后得到的多行中,全部被WHERE过滤掉了,这样最终结果集中将不含驱动表此行的相关信息,有时这不是我们希望的。故,引入内连接,外连接。
(1).对内连接,如驱动表的记录在被驱动表找不到匹配的记录,则最终结果集中将不含驱动表此行的相关信息。这就是默认下的表现。
(2).对外连接,如驱动表的记录在被驱动表找不到匹配的记录,则最终结果集中将依然包含一条此驱动表此行的对应行。只不过对应行中被驱动表各个列的数值为NULL。
_1.外连接下过滤条件–ON
使用外连接下,过滤使用ON语句。且ON子句必须要存在。
ON语句此时用于替代WHERE。但采用ON语句过滤下,对驱动表中某行和被驱动表中所有行构成的合并行都无法通过过滤下,依然会在最终结果集产生一个合并行其中被驱动表部分采用NULL。
_2.外连接下过滤–WHERE
外连接下,必须存在ON执行过滤。但ON过滤下,对驱动表所有在被驱动表中无法产生任何匹配的行,在最终结果集中均保留一行。如果希望对这些保留行执行过滤,需要依赖WHERE子句来进行。
3.连接语法
在MySQL中,根据选取的驱动表的不同,外连接可细分为左外连接和右外连接。
左外连接,可简称左连接;右外连接,可简称右连接;
_1.左连接的语法
如:SELECT * FROM t1 LEFT [OUTER] JOIN t2 ON 过滤条件 [WHERE 过滤条件];
括号中OUTER可以省略,不影响含义。
这里t1是驱动表,t2是被驱动表。
上述语句中ON子句不可省略,可以用ON替代WHERE。也可以让ON专注于过滤最终结果集中WHERE无法过滤的行。
_2.右连接的语法
如:SELECT * FROM t1 RIGHT [OUTER] JOIN t2 ON 连接条件 [WHERE 过滤条件];
此时驱动表是t2,t1是被驱动表。
_3.内连接的语法
下列这些语句含义一致,均采用内连接:
SELECT * FROM t1, t2;
SELECT * FROM t1 JOIN t2;
SELECT * FROM t1 INNER JOIN t2;
SELECT * FROM t1 CROSS JOIN t2;
内连接中ON子句没有存在必要。存在下等价于WHERE看待。
4.多表连接
如:SELECT * FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.m1 = t2.m2 AND t1.m1 = t3.m3;
另一种效果等价写法:SELECT * FROM t1 INNER JOIN t2 ON t1.m1 = t2.m2 INNER JOIN t3 ON t1.m1 = t3.m3;
5.表的别名
如:SELECT s1.number, s1.name, s1.major, s2.subject, s2.score FROM student_info AS s1 INNER JOIN student_score AS s2 WHERE s1.number = s2.number;
上述在FROM子句中给student_info,student_score起了别名,在查询语句其他地方可使用别名来引用表。
6.自连接
如:SELECT * FROM t1, t1;
会报错,报错不是因为不允许自连接,而是因为FROM子句中不允许两个表同名。
这样就可以了:SELECT * FROM t1 AS table1, t1 AS table2;
`