本练习来自W3Schools。
给定2个表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
表未与Jobs
表进行CROSSJOIN,因此不起作用。但是它似乎在嵌套在父调用中时起作用。这些表是以这种方式调用时自动交叉连接的吗?
有人可以告诉我这是如何运作的吗?
修改
本练习指导您使用子查询执行此操作,但我发现了一种更有意义的方法:
SELECT
first_name, last_name, salary
FROM
employees, jobs
WHERE
salary = min_salary
AND employees.job_id = jobs.job_id;
答案 0 :(得分:0)
表格由FROM中的逗号(","),CROSS JOIN或JOIN交叉连接。 (并且与OUTER JOIN添加的NULL扩展的不匹配行交叉连接。)这里嵌套的SELECT在WHERE中的表达式中,因此在概念上评估其值(交叉连接)外部WHERE' s FROM。
使用subselect的这个查询与具有JOIN的更简单的查询给出相同的答案。与算术表达式一样,您可以将SQL表达式重新排列为具有相同结果的不同形式。结果是根据它的编写方式,括号和优先级会影响它。实现可以做任何事情来获得结果。因此,您将阅读"概念"在FROM或#34;概念"中交叉连接评估顺序与实际完成的内容。主题是"查询优化"。 (实际上,查询实现,因为优化是如此重要。例如,在这里你真的不希望嵌套的SELECT 实际评估来自外部WHERE的FROM的每一行。)(见this answer&其链接重新查询语义。)
PS是的,练习是针对子选择的。使用子选择而不仅仅是JOIN会更好的问题将比引入子选择的问题更复杂。 (但是,在将min_salary
更改为MIN(salary)
后,您可以尝试重写以消除子选择。)
答案 1 :(得分:0)
如果是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
条件(通常类似于tab1.added > (...)
)分开。