0

我有一个查询来显示两个日期之间员工的出勤状态。

两个参数@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显示错误。

4

1 回答 1

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
于 2012-12-21T20:05:55.617 回答