Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ms access 基于ID对列访问行数据_Ms Access - Fatal编程技术网

Ms access 基于ID对列访问行数据

Ms access 基于ID对列访问行数据,ms-access,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/2

我有一个用于员工培训的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  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将第二个类日期和小时字段移动到同一行

我已经通过这个网站进行了研究,所有可能的解决方案似乎都过于复杂,因为我正在尝试实现

非常感谢你的帮助


谢谢

您必须使用子选择创建查询

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;
或者,您可以将嵌套的select存储为一个查询,我们称之为query1:

然后在第二个查询中使用它

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;

但是,无论是子查询还是第二个查询都是必需的。

这取决于您计划如何处理结果(如果它们只是为了显示)。这里是一个交叉表查询,它在值单元格中包含类日期和小时,在日期后的括号中包含小时

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);
这将允许任何数量的课程,而不仅仅是每个教师两个


来源:

我不会做这样的表-它违反了数据库规范化的第一条规则。您可以保留一个员工表和一个类表,并编写一个查询来提供所需的结果。这就是我想做的。保持原始表不变,但创建一个查询,将EmployeeID的公共字段移动到同一行。我只是不知道如何编写查询来获得结果。非常感谢Olivier。我用了你的第一个例子,效果很好。然而,有时员工只参加一次课程,并且只有一行条目。如何实现WHERE子句来检查ClassDate_2 ClassDate_1?IIfX.d1=X.d2,null,X.d2作为ClassDate_2,IIfec1.ClassHours=ec2.ClassHours,null,ec2.ClassHours作为ClassHours_2。但是,该解决方案最多只适用于每个员工两个级别。如果你有更多的类,你将不得不使用ChrisPadgham的解决方案。Olivier,非常感谢你的帮助。这个解决方案完全符合我的需要。我只需要将第二个IIF语句更改为与第一个IIF语句具有相同的表达式。上课时间总是一样的,所以我把它改成了检查上课日期是否与获取时间的条件相同。再次感谢您的解决方案。