我有一个查询来显示两个日期之间员工的出勤状态。
两个参数@FromDate
和@ToDate
被传递到存储过程中。此存储过程有一个 CTE,其中填写了此期间之间的所有日期。这在以下查询中由 T 表示。另一个 CTE,即 TUI,包含 T 的所有日期以及来自另一个名为 的表的所有相关 USER ID USER_INFO
。
其他需要连接的表是:
桌子: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。现在我想为所有员工显示所有这些日期。
例如:
如上所示,日期 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
显示错误。