2013-07-05 95 views
0

一个SQL查询我有一个考勤系统下列数据库模式:构建的架构

database schema

我怎么会写一个SQL查询来生成一天X项目的一个很好的报告?我需要它产生一个报告,有

员工姓名| TimeIn | TimeOut
Bob | 10:00 | 11:00
Sam | 10:30 | 18:00
Bob | 11:30 | 15:00

但是定义它是否是进入或退出时间的行由entryType(1代表输入,0代表输出)设置,所以我会替换TimeIn和TimeOut。

我的尝试是

`SELECT firstName, time from log INNER JOIN users on log.employeeID = users.employeeID WHERE date = GETDATE()` 

但这不处理的事实,有时是入门的,有些是退出。

请注意,每个日期可以有多个登录。

更新:

另一种尝试,但子查询返回多行

select firstName, (select time as timeIn from log where entryType = 1), (select time as timeOut from log where entryType = 0) inner join users on log.uID = users.uID from log group by uID 
+0

它的传统有一个去你自己,不要问这里的人为你做这一切。如果您有特定的问题/问题,请回到更具体的问题。 – RiggsFolly

+0

如何根据你的表格属性定义'TimeIn'和'TimeOut'? – Brian

+0

@RiggsFolly我的具体问题是显示报告中列出的时间和时间。定义条目是否是登录或注销的行是entryType,它是1代表in和0代表out。 – Wayneio

回答

1

这在Oracle中工作(道歉为非ANSI风格,但你应该得到漂移) ..

SELECT FORENAME,SURNAME,L1.TIME IN_TIME,L2.TIME OUT_TIME 
FROM EMPLOYEES EMP, LOG L1, LOG L2 
WHERE EMP.EMPLOYEE_ID = L1.EMPLOYEE_ID 
AND EMP.EMPLOYEE_ID = L2.EMPLOYEE_ID 
AND L1.ENTRYTYPE = 1 
AND L2.ENTRYTYPE = 0 
AND L2.TIME = (SELECT MIN(TIME) FROM LOG WHERE EMPLOYEE_ID = L2.EMPLOYEE_ID AND L2.ENTRYTYPE = 0 AND TIME > L1.TIME) 

更新:

啊,是的,没有考虑到。在这种情况下,你需要一个外连接。像这样(未经测试):

SELECT FORENAME,SURNAME,L1.TIME IN_TIME,L2.TIME OUT_TIME 
FROM EMPLOYEES EMP 
INNER JOIN LOG L1 ON EMP.EMPLOYEE_ID = L1.EMPLOYEE_ID AND L1.ENTRYTYPE = 1 
LEFT OUTER JOIN LOG L2 ON EMP.EMPLOYEE_ID = L2.EMPLOYEE_ID AND L2.ENTRYTYPE = 0 
         AND L2.TIME = (SELECT MIN(TIME) FROM LOG WHERE EMPLOYEE_ID = L2.EMPLOYEE_ID AND L2.ENTRYTYPE = 0 AND TIME > L1.TIME) 
+0

这工作完美,直到我注意到,如果用户已登录,但尚未登出,它不会显示该行! – Wayneio

+0

太棒了!更新完美 – Wayneio

0

该查询会给你的最早时间和最晚时间了雇员的。

SELECT E.FORENAME, 
(SELECT MIN(TIME) FROM LOG WHERE EMPLOYEEID = E.EMPLOYEEID AND ENTRYTYPE = 1 AND DATE = <YOUR DAYE>) AS "TIME_IN", 
(SELECT MAX(TIME) FROM LOG WHERE EMPLOYEEID = E.EMPLOYEEID AND ENTRYTYPE = 0 AND DATE = <YOUR DAYE>) AS "TIME_OUT" 
FROM EMPLOYEE E WHERE E.EMPLOYEEID = <EMPLOYEE ID> 
1

只要这样做就行。试试这个

SELECT FORENAME,SURNAME,LG.IN_TIME,LG.OUT_TIME FROM EMPLOYEES EMP INNER JOIN 
(SELECT MIN(TIME) IN_TIME,MAX(TIME) OUT_TIME,EMPLOYEE_ID FROM LOG 
GROUP BY EMPLOYEE_ID) LG ON EMP.EMPLOYEE_ID=LG.EMPLOYEE_ID 

注意:我没有包括入门型,因为在分钟的时间将被刷卡和最大的时间会刷出

更新

为了表示没有任何迹象的任何时间插入和尝试这样的事情,

SELECT FORENAME,SURNAME,LG.IN_TIME,LG.OUT_TIME,LG.no_of_ins, 
LG.no_of_outs FROM EMPLOYEES EMP INNER JOIN 
(SELECT MIN(TIME) IN_TIME,MAX(TIME) OUT_TIME,EMPLOYEE_ID, 
COUNT(CASE WHEN ENTRY_TYPE='I' THEN 1 ELSE O END noi) no_of_ins, 
COUNT(CASE WHEN ENTRY_TYPE='O' THEN 1 ELSE O END nou) no_of_outs, 
GROUP BY EMPLOYEE_ID) LG ON EMP.EMPLOYEE_ID=LG.EMPLOYEE_ID 
+0

谢谢,这很接近,但问题是如果有一天有多个登录,它将显示第一个登录(在time_in列中)和最后一个登录(在time_out列中),但不是多重登录。 – Wayneio

+0

尝试像我更新的答案 – Mari

+0

这很好,但我希望有多行登录,如用户在我更新的问题“鲍勃”所示。我想现在可能不可能。 – Wayneio