我正在生成每月出勤报告表,在其中我可以获取您在某天标记为出勤的那些员工的记录。这是我面临的问题,我需要报表中列出的每个员工,无论他的记录是否存在于出勤表中。
我使用了正确的外部联接,但id不适用于我,我环顾了其他解决方案,但没有人解决我的问题
Declare @fkSerial [numeric]=0;
Declare @attDateTime [datetime]='2019-04-01';
Declare @Company nvarchar(50)='ZCG';
Declare @Department nvarchar(50)=null;
Declare @StartOfMonth Datetime
Declare @EndOfMonth Datetime
declare @month int
declare @year int
declare @day int
set @month =DATEPART(month, @attDateTime)
set @year =DATEPART(year, @attDateTime)
set @day =DATEPART(day, @attDateTime)
set @StartOfMonth = DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0)
set @EndOfMonth = dateadd(SECOND,-1,DATEADD(MONTH,datediff(MONTH,0,GETDATE())+1,0));
With DATERANGE as(
SELECT DT =DATEADD(DD,0,@StartOfMonth)
WHERE DATEADD(DD, 1,@StartOfMonth) <=@EndOfMonth
UNION ALL
SELECT DATEADD(DD, 1, DT)
FROM DATERANGE
WHERE DATEADD(DD, 1, DT) <=@EndOfMonth
)
SELECT fkSerial,company,serial,
name,department,attINOUT,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30]
FROM
(SELECT Day(attDateTime) as d1,fkSerial,attDateTime, tblEmployInfo.company, tblEmployInfo.serial, tblAttendance.attINOUT,
tblEmployInfo.name,tblEmployInfo.department
FROM tblAttendance RIGHT outer JOIN
tblEmployInfo ON tblAttendance.fkSerial = tblEmployInfo.serial
where(
(tblAttendance.fkSerial = @fkSerial OR @fkSerial = 0) AND
(tblEmployInfo.department = @Department OR @Department is null) And
(tblAttendance.attDate in (select * from DATERANGE)) and
(tblEmployInfo.company= @Company or @Company is null)
and tblAttendance.attINOUT=0
)
group by tblAttendance.attDateTime,tblAttendance.fkSerial,tblEmployInfo.company,tblEmployInfo.serial,tblAttendance.attINOUT,tblEmployInfo.name,tblEmployInfo.department
having tblAttendance.attDateTime= min(tblAttendance.attDateTime)
) p
PIVOT(
MAx(p.attDateTime)
FOR d1 IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30] ) ) AS pvt
ORDER BY
pvt.fkSerial
我需要报告中列出的每个员工,无论他的记录是否存在于出勤表中
答案 0 :(得分:0)
您的WHERE状况有问题。您已指定tblAttendance.attINOUT = 0,而tblAttendance是您的左表,仅当左表中有记录时,该表才为true。因此,它会破坏您的RIGHT OUTER JOIN的目的。
尝试用ISNULL(tblAttendance.attINOUT,1)= 0替换tblAttendance.attINOUT = 0,然后查看是否获得所需的结果。希望这对您有所帮助:)。
答案 1 :(得分:0)
无论联接方向如何,辅助表字段(在这种情况下为tblAttendance)上的所有条件都必须位于联接(ON
子句)中,而不位于where中。只有路口的记录将具有相等的条件,并且结果将与INNER JOIN
相同。如果存在可空字段,则添加OR IS NULL
条件并不总是准确的。
SELECT Day(attDateTime) as d1,fkSerial,attDateTime, tblEmployInfo.company, tblEmployInfo.serial, tblAttendance.attINOUT,
tblEmployInfo.name,tblEmployInfo.department
FROM tblAttendance
RIGHT OUTER JOIN tblEmployInfo
ON tblAttendance.fkSerial = tblEmployInfo.serial
AND (
(tblAttendance.fkSerial = @fkSerial OR @fkSerial = 0) AND
(tblAttendance.attDate in (select * from DATERANGE)) AND
tblAttendance.attINOUT=0
)
WHERE
(tblEmployInfo.department = @Department OR @Department is null)
AND (tblEmployInfo.company= @Company or @Company is null)
此外,我想更改表的顺序并改用LEFT JOIN,我认为这是更标准的选择,但这是您的选择
SELECT Day(attDateTime) as d1,fkSerial,attDateTime, tblEmployInfo.company, tblEmployInfo.serial, tblAttendance.attINOUT,
tblEmployInfo.name,tblEmployInfo.department
FROM tblEmployInfo
LEFT JOIN tblAttendance
ON tblAttendance.fkSerial = tblEmployInfo.serial
AND (
(tblAttendance.fkSerial = @fkSerial OR @fkSerial = 0) AND
(tblAttendance.attDate in (select * from DATERANGE)) AND
tblAttendance.attINOUT=0
)
WHERE
(tblEmployInfo.department = @Department OR @Department is null)
AND (tblEmployInfo.company= @Company or @Company is null)