我在使用MYSQL时遇到了概念上的问题
让我们考虑两个表
Employee Salary
name salary Salary Grade
Nikhil 10000 10000 A
Akhil 10000 20000 B
Shubham NULL 10000 C
Abhishek 2000
并且sql查询是
select *
from Employee as e LEFT JOIN
SALARY as s
on s.Salary = e.salary
在输出中,我得到6行而不是4行。
name salary Salary Grade
Nikhil 10000 10000 A
Akhil 10000 10000 C
Nikhil 10000 10000 C
Akhil 10000 10000 A
Shubham NULL NULL NULL
Abhishek 2000 20000 B
答案 0 :(得分:2)
您得到正确的答案。 salary = 10000
中有两行带有Salary
的行。这两行都与Nikhil和Akhil匹配,导致重复。
inner join
会发生这种情况。如果没有NULL
值,就会发生这种情况。
应该将salary
的{{1}}更改为其他内容。
答案 1 :(得分:0)
结果正确。即使右表中没有匹配项,LEFT JOIN也会从左表返回所有记录(改为使用NULL填充字段)。 结果中的其余行来自10000工资的重复。
答案 2 :(得分:0)
首先,我假设您的示例数据集应包含Abhisek 20000
,而不是Abhisek 2000
,因为如果使用Abhisek 2000
,您将不会获得令人费解的结果
第二,使用*
返回重复的列。 (是的,我知道一个被称为salary
,另一个被称为Salary
-但是您要加入该列。它们是相同的值。不需要两次返回该值。)
第三,您似乎不了解JOIN
是如何建立其结果的。而您看到的“额外”行则来自您没有加入唯一数据这一事实。 Salary
中有 2 行,在10000
列中的值为Salary
。
因此,您的LEFT JOIN
从Salary
表开始,并尝试在Employee
表中为Salary列中的每个记录找到一个匹配项。这是从JOIN
构建行的方式:
Salary.Salary = 10000 AND Employee.salary = 10000
中的所有记录。 (这是“ A级”的JOIN
。)它将找到2个匹配项-一个匹配给Nikhil,另一个匹配给Akhil。因此,您从此JOIN
中获得了2行。Salary.Salary = 20000 AND Employee.salary = 20000
中的所有记录。 (这是“等级B”的JOIN
。)它找到1个匹配项(假设Abhisek的“真实”值为20000,而不是2000。)因此,您从此JOIN
中得到1行。您现在有3行。Salary.Salary = 10000 AND Employee.salary = 10000
中的所有记录。 (这是“ C级”的JOIN
。)它找到2个匹配项-一个匹配给Nikhil,另一个匹配给Akhil。因此,您从此JOIN
中得到2行。您现在有5行。JOIN
中的任何内容匹配,但这是原始SELECT ... FROM
子句的一部分。因此,您仍然可以返回该行。您现在有6行。最后,另一位受访者建议您通过执行以下操作来消除NULL
的结果:WHERE grade <> NULL
。错了这将消除所有行。如果要过滤出NULL
值,则需要添加以下内容:WHERE grade IS NOT NULL
。
答案 3 :(得分:0)