让我们一步一步来...
首先,您选择的实体在leave_request
表中。所以让我们从那里开始:
SELECT leave_request.* FROM leave_request
现在,您需要知道applied_by
所需结果中列的数据。所以你加入staff
表格:
SELECT
applied_staff.name AS applied_by
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
(请注意,我使用别名作为表名。稍后会派上用场。)
现在您需要知道applied_from
and applied_to
,您已经拥有了:
SELECT
applied_staff.name AS applied_by,
leave_request.applied_from,
leave_request.applied_to
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
现在您需要知道approved_from
和approved_to
,它们在leave_approval
表中:
SELECT
applied_staff.name AS applied_by,
leave_request.applied_from,
leave_request.applied_to,
admin_approval.approved_from,
admin_approval.approved_to
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
INNER JOIN leave_approval AS admin_approval ON leave_request.request_id = admin_approval.request_id
哦,现在我们有一个问题。存在一对多的关系,所以现在我们在结果中重复了请假请求。我们需要以某种方式过滤掉它。你没有具体说明如何,所以我要做几个假设:你想知道“管理员”批准的approved_from
和approved_to
只有一个“管理员”批准。
让我们在表连接中反映这些假设:
SELECT
applied_staff.name AS applied_by,
leave_request.applied_from,
leave_request.applied_to,
admin_approval.approved_from,
admin_approval.approved_to
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
INNER JOIN leave_approval AS admin_approval ON leave_request.request_id = admin_approval.request_id
INNER JOIN staff AS approved_staff ON admin_approval.approved_by = approved_staff.staff_id
INNER JOIN group AS approved_staff_group on approved_staff.group_id = approved_staff_group.group_id
WHERE
approved_staff_group.group_name = 'admin'
那应该更好。请注意,表别名在这里派上用场,因为我们现在staff
在同一个查询中有两个用于两个不同目的的表实例。所以我们需要区分它们。(请记住,我在这里盲目飞行,实际上无法测试任何这些。如果在此过程中遇到任何问题,请纠正我。我也是徒手编写这段代码,因为我没有 MySQL方便,所以如果还有语法错误,请告诉我。)
现在让我们将approved_admin
字段添加到结果中,该字段已经可用:
SELECT
applied_staff.name AS applied_by,
leave_request.applied_from,
leave_request.applied_to,
admin_approval.approved_from,
admin_approval.approved_to,
approved_staff.name AS approved_admin
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
INNER JOIN leave_approval AS admin_approval ON leave_request.request_id = admin_approval.request_id
INNER JOIN staff AS approved_staff ON admin_approval.approved_by = approved_staff.staff_id
INNER JOIN group AS approved_staff_group on approved_staff.group_id = approved_staff_group.group_id
WHERE
approved_staff_group.group_name = 'admin'
最后,我们需要知道approved_hr
. 并且null
被允许?那么,我们将为此使用不同的连接。我也在做出与上述类似的假设。让我们试试这个:
SELECT
applied_staff.name AS applied_by,
leave_request.applied_from,
leave_request.applied_to,
admin_approval.approved_from,
admin_approval.approved_to,
approved_staff.name AS approved_admin,
hr_staff.name AS approved_hr
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
INNER JOIN leave_approval AS admin_approval ON leave_request.request_id = admin_approval.request_id
INNER JOIN staff AS approved_staff ON admin_approval.approved_by = approved_staff.staff_id
INNER JOIN group AS approved_staff_group on approved_staff.group_id = approved_staff_group.group_id
LEFT OUTER JOIN leave_approval AS hr_approval ON leave_request.request_id = hr_approval.request_id
LEFT OUTER JOIN staff AS hr_staff ON hr_approval.approved_by = hr_staff.staff_id
LEFT OUTER JOIN group AS hr_staff_group ON hr_staff.group_id = hr_staff_group.group_id
WHERE
approved_staff_group.group_name = 'admin'
AND hr_staff_group.group_name = 'HR'
我不完全确定后者LEFT OUTER JOIN
。第一个肯定需要是允许null
值的连接,但我不确定查询引擎如何处理除此之外的连接。我希望它们INNER JOIN
在 initial 的范围内LEFT OUTER JOIN
。但我想所有这一切也确实取决于数据的完整性,我无法保证。
还值得注意的是,"Jack"
当值为"jack"
. 我没有在这段代码中进行任何字符串操作来实现这一点。如果值应该在数据中大写,则在数据中将其大写。
同样,我不能保证这个代码。但作为一个演练,它应该让你朝着正确的方向前进。正如我在对该问题的评论中提到的,如果您要编写 MySQL 代码,我真的建议您拿起一本关于 MySQL 的书。
编辑:我可以给出的一项建议是数据本身的结构。具体来说,leave_approval
那张桌子感觉有点乱,只有那张桌子引起了混乱。我有几个建议:
approval_type
在leave_approval
表中添加一个。至少这将表明它是管理员批准、人力资源批准还是任何其他类型的批准。(甚至还有其他类型吗?会有吗?)然后您还可以使用request_id
andapproval_type
作为组合主键,或者至少是组合唯一约束,以加强数据完整性并防止重复批准。
- 如果只有两种批准并且可能不会改变,请将它们都反映在
leave_approval
表格中。有一组用于 的列admin_approval_*
,一组用于hr_approval_*
。(每组都将包括staff_id
批准的相关日期。)然后request_id
它本身可能是leave_approval
使其与 . 一对一的主键leave_request
。这将极大地简化关系数据,实质上将记录转换为leave_approval
记录的一组可选附加信息leave_request
。连接会变得更简单,数据会更清楚地表达自己。