SQL 子查询中的内部联接

SQL Inner Join in Subqueries

此练习来自 W3Schools。

给定 2 table、EmployeesJobs,找到工资为 (first_name、last_name) 的员工的工资等于他们工作等级的最低标准。

http://www.w3resource.com/mysql-exercises/subquery-exercises/find-the-names-salary-of-the-employees-whose-salary-is-equal-to-the-minimum-salary-for-their-job-grade.php

给出的解决方案是:

SELECT 
    first_name, last_name, salary 
FROM 
    employees 
WHERE 
    employees.salary = (SELECT min_salary 
                        FROM jobs 
                        WHERE employees.job_id = jobs.job_id);

INNER JOIN 子查询

SELECT min_salary 
FROM jobs 
WHERE employees.job_id = jobs.job_id

不应该工作,因为 Employees table 尚未与 Jobs table 交叉连接。但是,它似乎在嵌套在父调用中时起作用。以这种方式调用时 table 是否会自动交叉连接?

谁能告诉我这是怎么回事?

编辑:

本练习指导您使用子查询来完成,但我发现了一种更有意义的方法:

SELECT 
    first_name, last_name, salary 
FROM 
    employees, jobs 
WHERE 
    salary = min_salary 
    AND employees.job_id = jobs.job_id;

表格通过逗号 (",")、CROSS JOIN 或 FROM 中的 JOIN 交叉连接。 (并与由 OUTER JOIN 添加的 NULL 扩展的不匹配行交叉连接。)这里嵌套的 SELECT 位于 WHERE 的表达式中,因此它的值在概念上针对(无交叉)外部的每一行进行评估来自哪里。

碰巧这个带有子选择的查询给出的答案与带有 JOIN 的更简单的查询给出的答案相同。与算术表达式一样,您可以将 SQL 表达式重新排列为具有相同结果的不同形式。结果取决于它的书写方式,括号和优先级会影响它。实现可以不惜一切代价获得该结果。因此,您将了解 FROM 中的 "conceptual" 交叉连接或 "conceptual" 评估顺序与实际完成的内容。题目是"query optimization"。 (实际上,查询实现因为优化非常重要。例如,在这里您真的不希望嵌套 SELECT 实际上 对来自外部 WHERE's FROM 的每一行进行评估。)(请参阅 this answer 及其有关查询语义的链接。)

PS 是的,练习是针对子选择的。使用子选择而不仅仅是 JOIN 确实会更好的问题将比适合引入子选择的问题更复杂。 (不过,在将 min_salary 更改为 MIN(salary) 后,您可以尝试重写以消除子选择。)

WHERE 子句中的子查询的情况下,您可以将其视为对每个 employees 行分别执行,因此您可以在子查询中使用父查询的字段。

是的,可以使用 JOIN 以更简单的方式完成,但这只是子查询的练习。 :)

您在问题末尾提出的查询是正确的,但无论如何我更喜欢明确使用 JOIN 子句以便更清楚。

SELECT first_name,last_name,salary 
FROM employees
JOIN jobs ON employees.job_id = jobs.job_id
WHERE employees.salary = jobs.min_salary AND ;

也许它在这里没有太大变化,但对于更复杂的查询它很有帮助。例如,通过这种方式,您可以将 JOIN 条件(通常如 tab1.id = tab2.tab1_id)与 logic/filtering 条件(如 tab1.added > (...))分开。