根据ID访问行数据到列

时间:2012-01-24 15:20:50

标签: ms-access

我有一个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编写查询以将第二个类日期和小时字段移动到同一行?

我已经通过这个网站进行了研究,所有可能的解决方案似乎都过于复杂,无法实现我的目标。

非常感谢您的帮助。

由于

2 个答案:

答案 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

确实有一个更简单的解决方案,但它假设该表按EmployeeIDClassDate排序。这种假设并不安全,因为没有保证自然排序顺序。 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