SQL 子查询中的内部联接
SQL Inner Join in Subqueries
此练习来自 W3Schools。
给定 2 table、Employees
和 Jobs
,找到工资为 (first_name、last_name) 的员工的工资等于他们工作等级的最低标准。
给出的解决方案是:
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 > (...)
)分开。
此练习来自 W3Schools。
给定 2 table、Employees
和 Jobs
,找到工资为 (first_name、last_name) 的员工的工资等于他们工作等级的最低标准。
给出的解决方案是:
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 > (...)
)分开。