我正在学习 sql 命令行,并通过终端在 mysql 中使用命令。我正在学习 INNER JOIN,我发现它很容易,但我有一个疑问,我必须解决否则无法传递给其他命令。
我有这四个表:departments、employees、employees_projects、projects
这些表格有以下内容:
部门: 身份证号码 名称 varchar(60)
员工: 身份证号码 名字 varchar(60) 姓氏 varchar(60) 薪水 Department_id int
employees_projects: project_id 整数 员工 ID 整数
项目: 身份证号码 标题 varchar(60) 开始日期 结束日期 预算内
当我想使用 INNER JOIN 连接两个表时,我只是这样使用它:
SELECT employees.first_name, employees.last_name, departments.name
FROM employees
INNER JOIN departments ON employees.department_id = departments.id;
当我想加入三个表时,我使用以下内容:
SELECT employees.first_name, employees.last_name, departments.name, employees_projects.project_id
FROM ( (employees
INNER JOIN departments ON employees.department_id = departments.id)
INNER JOIN employees_projects ON employees.id = employees_projects.employee_id);
这是我的问题:正如你所看到的,最后一行的结果会给我employees.first_name、employees.last_name、departments.name、employees_projects.project_id,这意味着我会得到雇员的姓名、姓氏、部门和他们正在处理的项目的 ID。现在,考虑到我们上面的表,我无法创建一个单行 SQL 查询,结果给我employees.first_name、employees.last_name、departments.name、projects.title。这意味着一个查询会为我提供员工的姓名、姓氏、部门和他们正在从事的项目名称。
是否可以在一行查询中实现这一点?
mysql>谢谢大家!
编辑帖子:
我创建了以下行:
SELECT employees.first_name, employees.last_name, departments.name, projects.title FROM ( (employees, projects INNER JOIN departments ON employees.department_id = departments.id) INNER JOIN employees_projects ON projects.id = employees_projects.project_id AND employees_projects.employee_id = employees.id);
但不幸的是我收到了这个错误,这很奇怪,因为看起来是正确的列:
mysql> SELECT employees.first_name, employees.last_name, departments.name, projects.title FROM ( (employees, projects INNER JOIN departments ON employees.department_id = departments.id) INNER JOIN employees_projects ON projects.id = employees_projects.project_id AND employees_projects.employee_id = employees.id);
ERROR 1054 (42S22): Unknown column 'employees.department_id' in 'on clause'
mysql>
答案 0 :(得分:2)
您可能熟悉算术符号。您可以使用任意数量的项创建算术表达式:
a + b + c + d
第一项之前没有任何内容。每个术语之间都有一个 +
。确实没有“主要”项,因为加法具有交换性的代数性质。该表达式具有相同的结果:
c + a + d + b
或术语的任何其他顺序。
在 SQL 中,连接是类似的。理论上你可以加入任意数量的表。
<table> INNER JOIN <table> ON <condition>
INNER JOIN <table> ON <condition>
INNER JOIN <table> ON <condition>
如果需要,您可以在此之后继续添加更多内容。 (我说在理论上是因为 MySQL 或任何其他 SQL 产品只是该语言的一种实现,它可能有实际限制。在 MySQL 的情况下,限制是每个查询 63 个表,但这不是语言的错,它只是如何MySQL 的代码实现了连接。)
FROM
不是表达式的一部分,它没有将任何表命名为“主”表。内连接具有可交换性,就像算术中的加法一样。事实上,MySQL 可以在运行您的查询时对表本身重新排序,前提是它可以使查询具有更好的性能。
您尝试过此连接:
FROM ( (employees, projects INNER JOIN departments
ON employees.department_id = departments.id)
INNER JOIN employees_projects
ON projects.id = employees_projects.project_id
AND employees_projects.employee_id = employees.id);
您混合了两种语法形式,这会导致问题。
带逗号的连接是 1989 年的,现在仍然有效。但是他们不能做 OUTER JOIN,所以语法在 1992 年更改为具有 INNER/OUTER JOIN 关键字。
但问题是带有 INNER/OUTER JOIN 关键字的语法比逗号具有更高的优先级。因此,就好像您的查询在查询引擎甚至承认 projects
是查询的一部分之前就加入了 departments
和 employees
。当它检查引用 ON
的 employees
条件时,它不知道该表。
这实际上已记录在案:https://dev.mysql.com/doc/refman/8.0/en/join.html 在页面底部附近搜索“JOIN 的优先级高于逗号运算符”。
解决方案是始终只使用 1992 风格的语法。我会按照@Adamszsz 在另一个答案中编写查询的方式来编写它。
答案 1 :(得分:1)
使用需要这样的东西:
select emp.first_name,emp.last_name,d.name,p.title , p.id from employees emp
join departments d on d.id = emp.department_id
join employees_projects empp on empp.employee_id = emp.id
join projects p on p.id = empp.project_id