我設想是這樣的......這樣的濾波的子查詢完成對員工的所有記錄沒有影響。
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.
都能跟得上(約需要由集團關於SQL註釋)的基礎上:MSFT
您好,歡迎來SO。你將需要提供一些實際的細節,以便我們提供幫助。發送鏈接到圖片不會導致任何人能夠幫助。請不要害怕爲查詢添加一些格式和空白空間,以免它們成爲文字牆。這裏是開始改善你的問題的好地方。 http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ –
你應該重新編輯你的答案並使用圖像..它的旁邊{}在工具欄中......這樣人們可以看到彼此並排。此外,與http://rextester.com/l/sql_server_online_compiler鏈接發佈的內容會再次提高一個數量級。 – JGFMK
您的from子句中的第一個表應該是employee表,並將其所有其他表留給它。由於您可能沒有任何出勤細節的員工,您需要一個包含所有員工的源表。此外,子查詢的where子句限制那些員工在要求的時間內沒有日期;因此您需要所有員工的來源。 – xQbert