我有一个MS Access数据库用于员工培训,每个员工每年要有两次课程。
该类的表格如下所示:
EmployeeID ClassDate ClassHours
1 1/1/2011 8
1 7/31/2011 7
2 2/1/2011 8
2 8/31/2011 7
3 3/1/2011 8
3 9/30/2011 7
我希望表格格式如下:
EmployeeID ClassDate_1 ClassHours_1 ClassDate_2 ClassHours_2
1 1/1/2011 8 7/31/2011 7
2 2/1/2011 8 8/31/2011 7
3 3/1/2011 8 9/30/2011 7
如何根据EmployeeID编写查询以将第二个类日期和小时字段移动到同一行?
我已经通过这个网站进行了研究,所有可能的解决方案似乎都过于复杂,无法实现我的目标。
非常感谢您的帮助。
由于
答案 0 :(得分:1)
您必须使用子选择
创建查询SELECT
X.EmployeeID,
X.d1 AS ClassDate_1, ec1.ClassHours AS ClassHours_1,
X.d2 AS ClassDate_2, ec2.ClassHours AS ClassHours_2
FROM
( (SELECT e.EmployeeID, Min(e.ClassDate) AS d1, Max(e.ClassDate) AS d2
FROM employee_classes AS e
GROUP BY e.EmployeeID) AS X
INNER JOIN employee_classes AS ec1
ON X.EmployeeID = ec1.EmployeeID AND X.d1 = ec1.ClassDate
)
INNER JOIN employee_classes AS ec2
ON X.EmployeeID = ec2.EmployeeID AND X.d2 = ec2.ClassDate;
或者,您可以将嵌套选择存储为查询(让我们称之为query1
):
SELECT e.EmployeeID, Min(e.ClassDate) AS d1, Max(e.ClassDate) AS d2
FROM employee_classes AS e
GROUP BY e.EmployeeID
然后在第二个查询中使用它
SELECT
X.EmployeeID,
X.d1 AS ClassDate_1, ec1.ClassHours AS ClassHours_1,
X.d2 AS ClassDate_2, ec2.ClassHours AS ClassHours_2
FROM
( query1 AS X
INNER JOIN employee_classes AS ec1
ON X.EmployeeID = ec1.EmployeeID AND X.d1 = ec1.ClassDate
)
INNER JOIN employee_classes AS ec2
ON X.EmployeeID = ec2.EmployeeID AND X.d2 = ec2.ClassDate;
如果没有显示小时数会更容易
SELECT e.EmployeeID, Min(e.ClassDate) AS ClassDate_1, Max(e.ClassDate) AS ClassDate_2
FROM employee_classes AS e
GROUP BY e.EmployeeID
确实有一个更简单的解决方案,但它假设该表按EmployeeID
和ClassDate
排序。这种假设并不安全,因为没有保证自然排序顺序。 Access可以随时“决定”以不同的方式重新组织记录。
SELECT
EmployeeID,
First(ClassDate) AS ClassDate_1, First(ClassHours) AS ClassHours_1,
Last(ClassDate) AS ClassDate_2, Last(ClassHours) AS ClassHours_2
FROM
employee_classes
GROUP BY
EmployeeID
ORDER BY
EmployeeID;
这里再次进行子选择可以帮助
SELECT
EmployeeID,
First(ClassDate) AS ClassDate_1, First(ClassHours) AS ClassHours_1,
Last(ClassDate) AS ClassDate_2, Last(ClassHours) AS ClassHours_2
FROM
(SELECT * FROM employee_classes ORDER BY EmployeeID, ClassDate)
GROUP BY
EmployeeID
ORDER BY
EmployeeID;
无论如何,都需要子查询或第二次查询。
答案 1 :(得分:0)
这取决于您计划如何处理结果,如果它们仅用于显示此处是交叉表查询,其中包含值单元格中的ClassDate和Hours(日期后括号中的小时数)
TRANSFORM Last([ClassDate] & " (" & [ClassHours] & ")") AS Details
SELECT Classes.EmployeeId
FROM Classes
GROUP BY Classes.EmployeeId
PIVOT "Class " & (DCount("[ClassNumber]","[Classes]","[ClassDate]<#" & Format$([ClassDate],"dd-mmm-yyyy") & "# AND [EmployeeId]=" & [EmployeeId])+1);
这将允许任何数量的课程,而不是每个教师两个课程。
output from crosstab http://www.solsup.com.au/images/classes.jpg