0

2つの日付の間の従業員の出席状況を表示するためのクエリがあります。

2つのパラメーター@FromDate@ToDate、がストアード・プロシージャーに渡されます。このストアドプロシージャには、この期間の間のすべての日付が入力されたCTEがあります。これは、以下のクエリではTで表されます。別のCTE、つまりTUIは、Tのすべての日付に加えて、という名前の別のテーブルからのすべての関連するUSERIDを保持します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値に関係なく、すべての日付を表示したい。上記のCTETは、2つの日付の間のすべての日付を一時テーブル#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 に答える