这里适合使用哪种连接方式(如果有的话)?

3

我是一个(my)SQL的新手,我需要知道如何(或是否可能)构建特定的查询。

我有3个表,如下所示:

Actions
-------
actionID | staffID | actionDetails | actionDate


Staff
-----
staffID | departmentID | userName | firstName | lastName


Departments
-----------
departmentID | departmentName

如您所见,departmentID 是 Staff 表中的外键,staffID 是 Actions 表中的外键。

我想根据 departmentID 拉取以下字段:

  • userName
  • firstName
  • lastName
  • actionDetails
  • actionDate

是否可以使用联接在单个查询中完成此操作,还是需要拉取 staffIDs 然后通过迭代进行操作?

再次说明,我刚开始学习这个,目前有点困难。我觉得我可能不太适合做这个!


1
这可以通过一次连接查询完成吗? 是的:请看这篇非常出色的文章,帮助解释连接查询:http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html 我们都是从某个地方开始的。将表格/连接视为数据“集合”,然后只需组合不同的集合即可获得数据。 - xQbert
4个回答

3

尝试使用这个查询。

select 
S.userName,
S.firstName,
S.lastName,
A.actionDetails,
A.actionDate
from Departments D 
join Staff S on d.departmentID=s.departmentID
join Actions A on s.staffID=A.staffID
WHERE D.departmentID = YourDeparmentID;

SQL中JOIN的类型 SQL中JOIN的类型


图片的链接即可。 - Muhammad Raheel
1
我不喜欢这张图片。将连接视为集合操作会使事情变得非常复杂!这并不能解释表之间的关系,这才是更加重要的。 - Cyril Gandon
实际上,我认为这张图片增强了答案。 - Dan Bracuk
1
这些图像(以及关于连接的视觉“解释”)应该被淘汰。它们是很好的解释,但只适用于集合操作(联合、交集、差集)。它们并没有解释连接,只是一种非常有限的连接方式。 - ypercubeᵀᴹ
谢谢!那个查询正是我所需要的。显然,我还有很多阅读要做。在我阅读更多内容后,这张图片可能会有所帮助,但我将其标记为已接受,因为这个查询非常完美(而且比图片更能帮助我理解这种特定类型的连接)。 - stoo
@stoo,我很高兴我的回答对你有所帮助。但它非常基础。你需要学习很多,尝试从**W3SCHOOLS**学习基础知识。 - Prahalad Gaggar

1
当然,这可以通过连接来完成。实际上,这就是连接的设计目的。在编写 SQL 时,您不应该考虑通过 ID 迭代;相反,应该考虑一次性获取数据,以“集合”形式呈现。您可以使用外键扩展这些集合,从而创建一个包含多个表的大型集合。
SELECT Staff.userName, Staff.firstName, Staff.lastName, 
  Actions.actionDetails, Actions.actionDate
FROM Staff
INNER JOIN Departments ON Departments.DepartmentID = Staff.DepartmentID
INNER JOIN Actions ON Actions.StaffID = Staff.StaffID

你会发现在其他答案中,人们使用了别名,比如Staff as s来简化他们的语句。这很常见,使得事情更易读;我在这里留下了它们,以使连接语法更清晰。
我提供的示例使用内连接--它将仅返回可以在StaffDepartmentsActions之间进行匹配的记录。如果你想要返回一个或多个表的所有行,并在找不到匹配项时返回null,你可以使用外连接。

1
我不愿意给出简单的答案,因为这可能只是你将要遇到的许多类似问题的开端。所以我宁愿告诉你我如何考虑它,也许这会帮助你解决其他问题。
正如上面的评论和其他答案所提到的,把它们看作集合。想想它们之间的关系。然后考虑要获取哪些列,并考虑如何确定要查看哪些行。
所以,首先,我编写一个FROM子句来处理记录来源(并给它们更短的名称或别名,以便更容易跟踪):
FROM Departments d
  INNER JOIN Staff s
  INNER JOIN Actions a

现在,它们是如何相关的?在这种情况下,它们与您提到的PK -> FK关系完全相同。因此,我将其添加到FROM子句中:
FROM Departments d
  INNER JOIN Staff s 
    ON s.DepartmentId = d.DepartmentId
  INNER JOIN Actions a
    ON a.StaffId = s.StaffId

现在,我使用SELECT子句决定要获取哪些列:
SELECT userName, firstName, lastName, actionDetails, actionDate

但是我应该从哪个表中获取这些列呢?我添加表别名:

SELECT s.userName, s.firstName, s.lastName, a.actionDetails, a.actionDate

(请注意,在这种情况下,没有出现在多个表中的列,因此别名并不是绝对必要的,尽管它们是非常好的实践。)
(最后,我添加了WHERE子句:)
WHERE d.DepartmentId = 20

或者你寻找的任何部门ID。

最终答案是这样的:

SELECT s.userName, s.firstName, s.lastName, a.actionDetails, a.actionDate
FROM Departments d
  INNER JOIN Staff s 
    ON s.DepartmentId = d.DepartmentId
  INNER JOIN Actions a
    ON a.StaffId = s.StaffId
WHERE d.DepartmentId = 20

0

对于部门ID为1

SELECT
    s.userName,
    s.firstName,
    s.lastName,
    a.actionDetails,
    a.actionDate
FROM Staff AS s
LEFT JOIN Departments AS d ON d.departmentID = s.departmentID
LEFT JOIN Actions AS a ON a.staffID = s.staffID
WHERE d.departmentID = 1;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接