为了更好地理解 SQL 连接的工作原理,我在理解查询返回的结果集时遇到了困难——我使用的表是:
员工
Id Name Salary Gender City
1 Sam 2500 Male London
5 Todd 3100 Male Toronto
3 John 4500 Male New York
6 Jack 7000 Male Shangri La
4 Sara 5500 Female Tokyo
2 Pam 6500 Female Sydney
和性别:
ID Gender
1 Male
2 Female
3 Unknown
第一个查询返回性别列上内部联接的所有列 -
SELECT *
FROM Employees
INNER JOIN Gender
ON Employees.Gender = Gender.Gender
返回结果-
Id Name Salary Gender City ID Gender
1 Sam 2500 Male London 1 Male
5 Todd 3100 Male Toronto 1 Male
3 John 4500 Male New York 1 Male
6 Jack 7000 Male Shangri La 1 Male
4 Sara 5500 Female Tokyo 2 Female
2 Pam 6500 Female Sydney 2 Female
这几乎是我所期望的。但是,当我更改比较运算符时 -
SELECT *
FROM Employees
INNER JOIN Gender
ON Employees.Gender != Gender.Gender
我原本以为会返回一个空集,返回了这个——
Id Name Salary Gender City ID Gender
4 Sara 5500 Female Tokyo 1 Male
2 Pam 6500 Female Sydney 1 Male
1 Sam 2500 Male London 2 Female
5 Todd 3100 Male Toronto 2 Female
3 John 4500 Male New York 2 Female
6 Jack 7000 Male Shangri La 2 Female
1 Sam 2500 Male London 3 Unknown
5 Todd 3100 Male Toronto 3 Unknown
3 John 4500 Male New York 3 Unknown
6 Jack 7000 Male Shangri La 3 Unknown
4 Sara 5500 Female Tokyo 3 Unknown
2 Pam 6500 Female Sydney 3 Unknown
虽然我可以有点看到不等于 (!=) 运算符将如何返回此结果,但它回避了以下问题:哪种类型的比较在连接谓词中有用哪些不是 - 连接类型 [inner, right, left...] 是否会对返回的结果产生不利影响,或者连接类型和比较是否可以解析为可操作的行为(换句话说,它是否总是必须 == )?另外,如果有任何资源可以帮助我,那就太好了。谢谢。
最佳答案
内部联接是两个表的笛卡尔积的子集。也就是说,一个表中的每一行都与另一个表中的每一行配对。
因此,如果一个表有 n 行,另一个表有 m 行,则笛卡尔积有 n * m 行。
on
子句过滤这些行。相等性是最常见的过滤器,此类连接通常称为等值连接。它们提供最多的优化机会,通常效率最高。
(外连接类似,但有一种机制来包含不匹配的行。)
通常,join
谓词至少包含一个相等比较(尽管这不是必需的)。其他比较——包括使用 exists
/in
的子查询——是允许的并且通常很有用。
任何体面的文档或教程或书籍都应该能够解释这一点。
在您的情况下,不存在
通常是意图。查找性别不在引用表中的员工:
SELECT e.*
FROM Employees e
WHERE NOT EXISTS (SELECT 1 FROM Gender g WHERE e.Gender = g.Gender)
当然,如果您使用主键引用表并包含适当的外键声明,则这样的查询是不必要的。
关于mysql - 加入谓词和比较运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57014569/