即使状态为空,也显示所有日期

时间:2012-12-21 19:04:06

标签: sql-server sql-server-2005

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

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

1 个答案:

答案 0 :(得分: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