我有以下查询,我希望表中的所有员工......怎么做?
这是我的表:
SELECT E.EmployeeId --assuming ID is the PK of Employee (E)
, tb1.monthDate
, ISNULL(present, 0 ) as present
, ISNULL(expected, 0 ) as expected
, ISNULL(late, 0 ) as late
FROM (SELECT distinct EmployeeId
FROM tblAttendanceDetails) E
LEFT JOIN (SELECT EmployeeId as id,count(Logintime) as present, month(Logintime) as monthDate
FROM tblAttendanceDetails
WHERE cast(Logintime as time)< cast('09:20' as time)
GROUP BY EmployeeId,month(Logintime)) as tb1
on E.EmployeeId = tb1.id
LEFT JOIN (SELECT EmployeeId,count(Logintime) as late, month(Logintime) as monthDate2
FROM tblAttendanceDetails
WHERE cast(Logintime as time)> cast('09:30' as time)
GROUP BY EmployeeId, month(Logintime)) as tb2
on E.EmployeeId=tb2.EmployeeId
and tb1.monthDate=tb2.monthDate2
LEFT JOIN (SELECT EmployeeId,count(Logintime) as expected,month(Logintime) as monthDate3
FROM tblAttendanceDetails
WHERE cast(Logintime as time) between cast('09:20' as time) and cast('09:30' as time)
GROUP BY EmployeeId,month(Logintime)) as tb3
on E.EmployeeId=tb3.EmployeeId
and tb1.monthDate=tb3.monthDate3
答案 0 :(得分:1)
我设想这样的事情......这样子查询中的过滤对员工的所有记录都没有影响。
SELECT E.id --assuming ID is the PK of Employee (E)
, tb1.monthDate
, coalesce(present, 0 ) as present
, coalesce(expected, 0 ) as expected
, coalesce(late, 0 ) as late
FROM Employee E
LEFT JOIN (SELECT EmployeeId as id,count(Logintime) as present, month(Logintime) as monthDate
FROM tblAttendanceDetails
WHERE cast(Logintime as time)< cast('09:20' as time)
GROUP BY EmployeeId,month(Logintime)) as tb1
on E.ID = tb1.ID
LEFT JOIN (SELECT EmployeeId,count(Logintime) as late, month(Logintime) as monthDate2
FROM tblAttendanceDetails
WHERE cast(Logintime as time)> cast('09:30' as time)
GROUP BY EmployeeId, month(Logintime)) as tb2
on E.id=tb2.EmployeeId
and tb1.monthDate=tb2.monthDate2
LEFT JOIN (SELECT EmployeeId,count(Logintime) as expected,month(Logintime) as monthDate3
FROM tblAttendanceDetails
WHERE cast(Logintime as time) between cast('09:20' as time) and cast('09:30' as time)
GROUP BY EmployeeId,month(Logintime)) as tb3
on E.id=tb3.EmployeeId
and tb1.monthDate=tb3.monthDate3
也许你的意思是:
SELECT E.id --assuming ID is the PK of Employee (E)
, E.monthDate
, coalesce(present, 0 ) as present
, coalesce(expected, 0 ) as expected
, coalesce(late, 0 ) as late
FROM (SELECT distinct EmployeeID ID, month(Logintime) as monthdate
FROM tblAttendanceDetails) E
LEFT JOIN (SELECT EmployeeId as id,count(Logintime) as present, month(Logintime) as monthDate
FROM tblAttendanceDetails
WHERE cast(Logintime as time)< cast('09:20' as time)
GROUP BY EmployeeId,month(Logintime)) as tb1
on E.ID = tb1.ID
and E.Monthdate = t1.monthdate
LEFT JOIN (SELECT EmployeeId,count(Logintime) as late, month(Logintime) as monthDate2
FROM tblAttendanceDetails
WHERE cast(Logintime as time)> cast('09:30' as time)
GROUP BY EmployeeId, month(Logintime)) as tb2
on E.id=tb2.EmployeeId
and E.monthDate=tb2.monthDate2
LEFT JOIN (SELECT EmployeeId,count(Logintime) as expected,month(Logintime) as monthDate3
FROM tblAttendanceDetails
WHERE cast(Logintime as time) between cast('09:20' as time) and cast('09:30' as time)
GROUP BY EmployeeId,month(Logintime)) as tb3
on E.id=tb3.EmployeeId
and E.monthDate=tb3.monthDate3
或许我们可以使用窗口函数消除连接和子查询。
SELECT EmployeeID as ID
, month(Logintime) as MonthDate
, sum(case when cast(Logintime as time) < cast('09:20' as time)
then 1 else 0 end) over (partition by month(Logintime),employeeID) as present
, sum(case when cast(Logintime as time)> cast('09:30' as time)
then 1 else 0 end) over (partition by month(Logintime),employeeID) as expected
, sum(case when cast(Logintime as time) between cast('09:20' as time) and cast('09:30' as time)
then 1 else 0 end) over (partition by month(Logintime),employeeID) as late
FROM tblAttendanceDetails E
--GROUP BY EmployeeID, month(LoginTime) -- is the group by needed don't think so since we're using the window functions and the case abstracts the logintime to 1/0 that is now summed...but not sure w/o testing.
基于:MSFT
,没有(关于需要分组的SQL评论)