为简单起见,假设所有相关字段都不是NOT NULL
。
你可以做:
SELECT
table1.this, table2.that, table2.somethingelse
FROM
table1, table2
WHERE
table1.foreignkey = table2.primarykey
AND (some other conditions)
要不然:
SELECT
table1.this, table2.that, table2.somethingelse
FROM
table1 INNER JOIN table2
ON table1.foreignkey = table2.primarykey
WHERE
(some other conditions)
这两个在MySQL
以相同的方式工作吗?
INNER JOIN
是您应该使用的 ANSI 语法。
它通常被认为更具可读性,尤其是当您加入大量表时。
只要有需要,它也可以很容易地用OUTER JOIN
替换。
WHERE
语法是面向关系模型的更多。
两个表JOIN
ed 的结果是应用了过滤器的表的笛卡尔积,其仅选择具有匹配的连接列的那些行。
使用WHERE
语法更容易看到这一点。
至于你的例子,在 MySQL(以及一般的 SQL)中,这两个查询是同义词。
另请注意,MySQL 也有一个STRAIGHT_JOIN
子句。
使用此子句,您可以控制JOIN
顺序:在外部循环中扫描哪个表以及在内部循环中扫描哪个表。
您无法使用WHERE
语法在 MySQL 中控制此操作。
其他人指出,INNER JOIN 有助于人类的可读性,这是首要任务; 我同意。让我试着解释为什么连接语法更具可读性。
一个基本的 SELECT 查询是这样的:
SELECT stuff
FROM tables
WHERE conditions
SELECT 子句告诉我们, 正是我们找回; FROM 子句告诉我们从哪里获取它,WHERE 子句告诉我们我们得到了哪些 。
JOIN 是关于表的声明,它们如何绑定在一起(概念上,实际上,绑定到单个表中)。任何控制表的查询元素 - 我们从中获取东西 - 在语义上属于 FROM 子句(当然,这是 JOIN 元素所在的位置)。将 join-elements 放入 WHERE 子句会将which和where-from混合在一起; 这就是 JOIN 语法首选的原因。
在 ON / WHERE 中应用条件语句
在这里,我已经解释了逻辑查询处理步骤。
参考:内部 Microsoft®SQLServer™2005 T-SQL 查询
出版商:微软出版社
发布日期:2006 年 3 月 7 日
打印 ISBN-10:0-7356-2313-9
打印 ISBN-13:978-0-7356-2313-2
页数:640
内部 Microsoft®SQLServer™2005 T-SQL 查询
(8) SELECT (9) DISTINCT (11) TOP <top_specification> <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH {CUBE | ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY <order_by_list>
与其他编程语言不同的 SQL 的第一个显着方面是代码的处理顺序。在大多数编程语言中,代码按其编写顺序进行处理。在 SQL 中,处理的第一个子句是 FROM 子句,而首先出现的 SELECT 子句几乎是最后处理的。
每个步骤都会生成一个虚拟表,用作以下步骤的输入。这些虚拟表对调用者(客户端应用程序或外部查询)不可用。只有最后一步生成的表才会返回给调用者。如果查询中未指定某个子句,则只需跳过相应的步骤。
如果步骤的描述现在似乎没有多大意义,请不要太担心。这些是作为参考提供的。在场景示例之后的部分将更详细地介绍这些步骤。
FROM:在 FROM 子句的前两个表之间执行笛卡尔积(交叉连接),结果生成虚拟表 VT1。
ON:ON 滤波器应用于 VT1。只有<join_condition>
为 TRUE 的行才会插入 VT2。
OUTER(join):如果指定了 OUTER JOIN(而不是 CROSS JOIN 或 INNER JOIN),则保留的表中未找到匹配项的行将作为外行添加到 VT2 的行中,从而生成 VT3。如果 FROM 子句中出现两个以上的表,则在最后一个连接的结果和 FROM 子句中的下一个表之间重复应用步骤 1 到步骤 3,直到处理完所有表。
WHERE:WHERE 过滤器应用于 VT3。只有<where_condition>
为 TRUE 的行才会插入 VT4。
GROUP BY:VT4 中的行根据 GROUP BY 子句中指定的列列表按组排列。 VT5 已生成。
CUBE | ROLLUP:超级组(组的组)被添加到 VT5 的行中,生成 VT6。
HAVING:HAVING 过滤器应用于 VT6。只有<having_condition>
为 TRUE 的组才会插入 VT7。
SELECT:处理 SELECT 列表,生成 VT8。
DISTINCT:从 VT8 中删除重复的行。生成 VT9。
ORDER BY:VT9 中的行根据 ORDER BY 子句中指定的列列表进行排序。生成游标(VC10)。
TOP:从 VC10 的开头选择指定的行数或百分比。生成表 VT11 并将其返回给调用者。
(在 ON / WHERE 中应用条件语句在少数情况下不会有太大区别。这取决于您加入的表数和每个连接表中可用的行数)