前缀表示什么?
如果您查看您所质疑的示例查询的FROM 子句,您应该注意到在完整表名之后指定的表别名。有时使用别名只是为了缩短需要完整拼写的表名,但大多数情况下需要使用别名来消除FROM 中多个表中类似名称的列之间的歧义。
SELECT
-- Get the email column from the table aliased
-- as `m` (table1)
m.email
FROM
-- table1 aliased as m
table1 AS m
-- table1 aliased as e
INNER JOIN table2 AS e ON....
考虑两个相关的表,table1 和 table2。他们都有一个名为email 的列。在SELECT 列表中,您不能只指定email,因为RDBMS 不会知道您想要哪一个。相反,您必须使用表名对其进行限定。由于表在FROM 中的别名为m, e,因此您必须使用SELECT 中的别名而不是完整的表名。
MS SQL Server documentation on table aliases...
在预期条件的上下文中指定的非布尔类型表达式,靠近 ')'
在您的联接的ON 子句中,您只需提供列名email,我们可以假设它是与两个表相关的公共值。连接的 ON 子句需要一个布尔表达式,其中 true 值在表之间进行逐行比较会返回一行。
所以ON 子句需要一个带有两侧的布尔表达式,或者返回 TRUE 的东西。在您的情况下,email 列之间是相等的
SELECT DISTINCT
-- Must qualify email since both tables have it
-- Using the full table name, or its alias if an alias
-- was provided in `FROM`.
[Table 1].email,
status_type,
status_value_text
FROM
ent.[Table 1]
-- Equality between email columns completes the join
JOIN [Table 2] ON [Table 1].email = [Table 2].email
ON 中的表达式可以是 anything,其计算结果为 TRUE。它不必是列值之间的精确匹配,尽管精确匹配是迄今为止最常见的用例。例如,您可以说ON 1 = 1,这是始终正确的。结果行集将匹配从[Table 1] 的每一行到[Table 2] 的每一行(这是一个笛卡尔积)。它也可能是ON 1 = 2,这是从不正确的,因此基本上没有意义,因为它永远不会返回行。
使用类似于您尝试的ON email 的语法,一些RDBMS 系统支持USING() 代替ON,允许您指定相等列而不是布尔表达式。因此,您也可以将其表达为
FROM
ent.[Table 1]
JOIN [Table 2] USING (email)
另见What's the difference between ON and USING