2012-07-10 27 views
-5

休假管理我有4个表像图所示加入在MySQL在PHP和MySQL

表:leave_request

+------------+----------+--------------+------------+----------------------+ 
| request_id | staff_id | applied_from | applied_to | status    | 
+------------+----------+--------------+------------+----------------------+ 
|  1  | 10  | 01-07-2012 | 02-07-2012 | approved    | 
|  2  | 12  | 02-07-2012 | 02-07-2012 | awaiting HR approval | 
+------------+----------+--------------+------------+----------------------+ 

表:leave_approval

+-------------+-------------+---------------+-------------+ 
| request_id | approved_by | approved_from | approved_to | 
+-------------+-------------+---------------+-------------+ 
| 1  |  1  | 01-07-2012 | 02-07-2012 | 
| 1  |  2  | 01-07-2012 | 02-07-2012 | 
| 2  |  1  | 02-07-2012 | 02-07-2012 | 
+-------------+-------------+---------------+-------------+ 

表:员工

+-----------+-------+----------+ 
| staff_id | name | group_id | 
+-----------+-------+----------+ 
| 1  | jack |  1 | 
| 2  | jill |  2 | 
| 10  | sam |  3 | 
| 12  | david |  3 | 
+-----------+-------+----------+ 

表格:gr牛津大学出版社

+-----------+------------+ 
| group_id | group_name | 
+-----------+------------+ 
| 1  | admin | 
| 2  |  HR  | 
| 3  | staff | 
+-----------+------------+ 

我需要通过连接这些表作报告,它应该如下:

+----------+------------+----------+-------------+-----------+--------------+-----------+ 
|applied_by|applied_from|applied_to|approved_from|approved_to|approved_admin|approved_hr| 
+----------+------------+----------+-------------+-----------+--------------+-----------+ 
| sam | 01-07-2012 |02-07-2012|01-07-2012 |02-07-2012 | Jack   | Jill  | 
| david | 02-07-2012 |02-07-2012|02-07-2012 |02-07-2012 | Jack   | null  | 
+----------+------------+----------+-------------+-----------+--------------+-----------+ 

感谢提前:)

+1

在此先感谢? [您尝试过什么?](http://WhatHaveYouTried.com) – 2012-07-10 10:26:22

+0

您选择的实体位于'leave_request'表中。所选数据的其余部分从其他表中加入。你有什么困难?如果你想知道'JOIN'是如何工作的,我建议你选择一本关于MySQL的初学者书籍。 – David 2012-07-10 10:36:10

+0

我看到这个问题已经得到-3。好吧,我没有在这里发布任何内容,我也不是MySQL的专家。我在我的查询中得到了一切,我认为没有人观察到leave_approval表,它有两行与具有不同staff_id的相同request_id。我想通过检查groups表在字段(approved_admin和approved_hr)中显示该名称。我不知道该怎么做。这是我的问题。 '希望我很清楚' – 2012-07-10 10:53:16

回答

1

让我们把它一步一步。 ..

首先,您选择的实体位于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_fromapplied_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_fromapproved_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_fromapproved_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值的连接,但我不确定查询引擎如何处理连接。我宁愿他们在最初的LEFT OUTER JOIN范围内的INNER JOIN s。但我想所有这些都取决于数据的完整性,我不能保证。

值得注意的是,当声明值为"jack"时,您声称想将"Jack"作为输出。我没有在这段代码中做任何字符串操作来实现这一点。如果该值应该在数据中大写,则将其大写在数据中。

再次,我不能保证此代码。但作为一个步行,它应该让你朝着正确的方向前进。正如我在对这个问题的评论中提到的,如果你打算编写MySQL代码,我真的建议你拿一本关于MySQL的书。

编辑:我可以给出的一个建议是数据本身的结构。具体来说,leave_approval桌子感觉有点凌乱,而这正是造成混淆的桌子。我有几条建议:

  1. approval_type加到leave_approval表中。至少这将表明它是否是管理员批准,人力资源批准或任何其他类型的批准。 (是否还有其他类型?是否会有?)然后,您还可以使用request_idapproval_type作为组合主键或至少一个组合的唯一约束,以强化更好的数据完整性并防止重复的批准。
  2. 如果只有两种批准,并且可能不会更改,请在leave_approval表中反映它们。为admin_approval_*设置一组列,为hr_approval_*设置一组列。 (每组将包括staff_id以及批准的相关日期。)然后request_id本身可能是leave_approval上的主键,使其与leave_request一一对应。这将大大简化关系数据,实质​​上将leave_approval记录转换为leave_request记录的可选附加信息集。连接会变得简单得多,数据会更清晰地表达出来。