与SQL标准相比, 语法 扩展了。后者只接受 table_reference
,而不是在一对括号内的列表。 如果我们将 table_reference
项目 列表中的每个逗号 视为等同于内部 联接,则这是保守扩展 。 例如:
SELECT * FROM t1 LEFT JOIN(t2,t3,t4)
ON(t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)
相当于:
SELECT * FROM t1 LEFT JOIN(t2 CROSS JOIN t3 CROSS JOIN t4)
ON(t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)</span>
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT,b INT);
CREATE TABLE t3(b INT);
INSERT INTO t1(a) VALUES(1),(2);
INSERT INTO t2(a,b) VALUES(1,101);
INSERT INTO t3(b) VALUES(101)
SELECT * FROM t1;
SELECT * FROM t2;
SELECT * FROM t3;
(1) SELECT * FROM t1
LEFT JOIN (t2 LEFT JOIN t3 ON t2.b=t3.b OR t2.b IS NULL)
ON t1.a=t2.a;
等同于 SELECT * FROM t1 LEFT JOIN(t2,t3) ON t1.a = t2.a
WHERE(t2.b = t3.b OR t2.b IS NULL)
结果:
(2)值得注意的是,给定跟(1)同样的条件,切返回不用的结果集
SELECT *
FROM (t1 LEFT JOIN t2 ON t1.a=t2.a)
LEFT JOIN t3
ON t2.b=t3.b OR t2.b IS NULL;
因此,如果我们在带有外连接运算符的连接表达式中省略括号,我们可能会更改原始表达式的结果集。 更准确地说,我们不能忽略左外连接操作的右操作数和右连接操作的左操作数中的括号。 换句话说,我们不能忽略外连接操作的内部表表达式的括号。 可以忽略其他操作数(外部表的操作数)的括号。
对于a LEFT JOIN
,如果 WHERE
生成的 NULL
行 的 条件始终为false ,则将 LEFT JOIN
其更改为内部联接。 例如, WHERE
如果条款是在下面的查询错误的 t2.column1
是 NULL
:
SELECT * FROM t1 LEFT JOIN t2 ON(column1)WHERE t2.column2 = 5;
因此,将查询转换为内部联接是安全的:
SELECT * FROM t1,t2 WHERE t2.column2 = 5 AND t1.column1 = t2.column1;
对于
SELECT * FROM t1
LEFT JOIN t2
ON t2.a = t1.a
LEFT JOIN t3
ON t3.b = t2.b
where t3.b> 0
首先转换为查询:
SELECT * FROM t1
LEFT JOIN t2
ON t2.a = t1.a
INNER JOIN t3
ON t3.b = t2.b
where t3.C> 0
这相当于查询:
同样可以转换为:
SELECT * FROM t1 LEFT JOIN
(t2,t3)
ON (t2.A=t1.a AND t3.b=T2.b)
WHERE t3.b > 0