2017-07-14 60 views
0

我有以下查詢,我希望所有員工都出現在表中......如何做到這一點?SQL查詢:如何從給定的SQL查詢中獲取所有員工

這是我的表:

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:

+0

您好,歡迎來SO。你將需要提供一些實際的細節,以便我們提供幫助。發送鏈接到圖片不會導致任何人能夠幫助。請不要害怕爲查詢添加一些格式和空白空間,以免它們成爲文字牆。這裏是開始改善你的問題的好地方。 http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ –

+0

你應該重新編輯你的答案並使用圖像..它的旁邊{}在工具欄中......這樣人們可以看到彼此並排。此外,與http://rextester.com/l/sql_server_online_compiler鏈接發佈的內容會再次提高一個數量級。 – JGFMK

+0

您的from子句中的第一個表應該是employee表,並將其所有其他表留給它。由於您可能沒有任何出勤細節的員工,您需要一個包含所有員工的源表。此外,子查詢的where子句限制那些員工在要求的時間內沒有日期;因此您需要所有員工的來源。 – xQbert

回答

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. 

都能跟得上(約需要由集團關於SQL註釋)的基礎上:MSFT

+0

對不起,我給出的圖像是tblattendanceDetails的圖像,還有另一個表tblEmployee包含全部員工 –

+0

對。我想說,如果您希望作爲員工的所有員工在查詢時沒有任何詳細信息,您必須使用員工表;因爲你說你想要所有的員工,你需要一個包含所有員工的數據集......我很明顯錯過了一些東西,但是...... – xQbert

+0

好的......當你說:「所有在場的員工」你的意思是tblAttendanceDetails?如果是這樣,只需替換我的員工'(從tblAttendanceDetails中選擇不同的ID)E' – xQbert