2012-12-21 31 views
0

我有一個查詢,顯示兩個日期之間的員工出勤狀況。顯示所有日期,即使狀態爲空

兩個參數,@FromDate@ToDate,被傳遞到存儲過程。此存儲過程具有一個CTE,其中包含填入此期間的所有日期。在下面的查詢中,這由T表示。另一個CTE,即TUI,保存T的所有日期加上來自另一個名爲USER_INFO的表的所有相關用戶ID。

需要被加入

其他表:

表:USER_INFO

USER_ID INT P.K, DISPLAY_NAME Varchar 

表:ATTDETAILS

inUserID INT P.K, dtAttendanceDate DateTime, inAttendanceStatusId INT F.K 

表:Att_Status_Master

inAttendanceStatusId INT P.K, ATTStatus VARCHAR 

列,AttStatus上文表Att_Status_Master,持有值:Present, Absent

與下面碼的問題是,它給結果僅當任何AttStatus的存在對於特定日期。如果沒有員工在特定日期標記出席人數,則該日期不在結果集中。

我想在不考慮NULL值的顯示所有的日期。上面提到的CTE T將兩個日期之間的所有日期提供給臨時表#Results。現在我想爲所有員工展示所有這些日期。

例如:

enter image description here

正如你可以在上面看到,日期01/DEC/2012有沒有地位,但它仍然應該顯示在結果。而下面的查詢,它不會被顯示。以下查詢僅顯示填入AttStatus的記錄。

最終的存儲過程的代碼如下:

@FromDate DateTime /* Input Parameter */ 
@ToDate  DateTime /* Input Parameter */ 

If OBJECT_ID('tempdb..#Results',N'U') IS NOT NULL 
    DROP TABLE #Results 

DECLARE @StartDate DateTime 
DECLARE @EndDate DateTime 

@StartDate = Convert(Varchar(25),@FromDate,112) 
@EndDate = Convert(Varchar(25), (DateAdd(DAY,15,@FromDate)),112) 

;With T (tempStoredDate) 
AS (
    select @StartDate 
    union all 
    select dateadd(day,1,tempStoredDate) from T where T.tempStoredDate < @EndDate 
), 
TUI AS 
(
    select T.tempStoredDate, UI.user_id, ui.display_name, dbo.GetEmployeeCode(UI.user_id) AS EmpCode from T 
    cross join user_info UI 
) 

select TUI.EmpCode, UI.user_id, UI.Display_Name, TUI.tempStoredDate, AD.dtAttendanceDate, ASM.AttStatus 
INTO #Results From TUI 
left outer join user_info UI 
on TUI.user_id = UI.user_id 
left outer join Att_Details AD 
on UI.user_id = AD.inUserId 
inner join Att_Status_Master ASM 
on ASM.inAttendanceStatusId = AD.inAttendanceStatusId 
where Convert(Varchar(25),dtAttendanceDate,112) = Convert(Varchar(25),tempStoredDate,112) 
group by TUI.tempStoredDate,UI.user_id,UI.Display_Name,TUI.EmpCode,AD.dtAttendanceDate,AD.inAttendanceStatusId,ASM.AttStatus 

我注意到,因爲WHERE子句中發生這種情況。如果我忽略WHERE子句,則所有日期都可見,但AttStatus顯示爲錯誤。

+2

where子句你指的是哪個? – bonCodigo

+1

你確定它不是Att_Status_Master的內部連接嗎?丟失的行具有NULL的狀態,其不會通過連接標準 –

+0

@NathanSkerl我試着左加入爲好。 – RKh

回答

1

你要移動的條件WHERE子句的LEFT JOIN中

From TUI 
left join user_info UI on TUI.user_id = UI.user_id 
left join Att_Details AD on UI.user_id = AD.inUserId 
    and Convert(Varchar(25),AD.dtAttendanceDate,112) 
     = Convert(Varchar(25),TUI.tempStoredDate,112) /* condition moved here */ 
join Att_Status_Master ASM 
    on ASM.inAttendanceStatusId = AD.inAttendanceStatusId 
group by 
    TUI.tempStoredDate, UI.user_id, UI.Display_Name, 
    TUI.EmpCode, AD.dtAttendanceDate, AD.inAttendanceStatusId, ASM.AttStatus 
+0

請參見[左連接的條件](http://wiki.lessthandot.com/index.php/WHERE_conditions_on_a_LEFT_JOIN) – ErikE

+0

儘管如此,它仍然只顯示dtAttendanceDate存在的員工。不顯示所有員工和所有日期。 – RKh

+0

最後的連接是將前面的左連接變成內連接(從而消除NULL行)。你是否有意將它放在'left join Att_Details AD'和'on UI.user_id = AD.inUserId'之間? –

相關問題