SQL查询:如何从给定的SQL查询中获取所有员工

时间:2017-07-14 13:27:11

标签: sql-server

我有以下查询,我希望表中的所有员工......怎么做?

这是我的表:

This is my table

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

这是我的查询结果: this is my query result:

1 个答案:

答案 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评论)