考勤问题,有班次,有工作日历,有打卡记录,如何做考勤分析
考勤问题,有班次,有工作日历,有打卡记录,如何做考勤分析
--班次CREATE TABLE [dbo].[BANCI]( [Code] [nvarchar](20) NOT NULL, [Item] [int] NOT NULL, [KTIME] [nvarchar](20) NULL, [KSTA] [nvarchar](20) NULL, [KLST] [nvarchar](20) NULL) ON [PRIMARY]--打卡记录CREATE TABLE [dbo].[CardList]( [Emp] [nvarchar](20) NULL, [CDate] [nvarchar](20) NULL, [CardTime] [nvarchar](20) NULL) ON [PRIMARY]--工作日历CREATE TABLE [dbo].[WorkDate]( [Emp] [nvarchar](20) NULL, [CDate] [nvarchar](20) NULL, [Banci] [nvarchar](20) NULL) ON [PRIMARY]
select a.emp,b.cdate,c.ctype+': '+case when cast(a.cardtime as datetime) between cast(c.KSTA as datetime) and cast(c.KLST as datetime) then '正常'else '未刷卡' end 'ctype'from (select row_number() over(partition by cdate order by cardtime) rn,* from CardList) a inner join WorkDate b on a.emp=b.emp and a.cdate=b.cdateinner join BANCI c on b.banci=c.code and a.rn=c.itemwhere b.banci is not null emp cdate ctype-------------------- -------------------- ----------------------------YXX0004 2011-08-01 上午上班: 正常YXX0004 2011-08-01 上午下班: 正常YXX0004 2011-08-01 下午上班: 正常YXX0004 2011-08-01 下午下班: 正常YXX0004 2011-08-02 上午上班: 正常YXX0004 2011-08-02 上午下班: 正常YXX0004 2011-08-02 下午上班: 正常YXX0004 2011-08-03 上午上班: 正常YXX0004 2011-08-03 上午下班: 正常YXX0004 2011-08-03 下午上班: 正常YXX0004 2011-08-03 下午下班: 正常YXX0004 2011-08-04 上午上班: 正常YXX0004 2011-08-04 上午下班: 正常YXX0004 2011-08-04 下午上班: 正常YXX0004 2011-08-04 下午下班: 正常YXX0004 2011-08-05 上午上班: 正常YXX0004 2011-08-05 上午下班: 正常YXX0004 2011-08-05 下午上班: 正常YXX0004 2011-08-05 下午下班: 正常YXX0004 2011-08-07 上午上班: 正常YXX0004 2011-08-07 上午下班: 正常YXX0004 2011-08-07 下午上班: 未刷卡YXX0004 2011-08-07 下午下班: 正常YXX0004 2011-08-08 上午上班: 正常YXX0004 2011-08-08 上午下班: 正常YXX0004 2011-08-08 下午上班: 正常YXX0004 2011-08-08 下午下班: 正常YXX0004 2011-08-09 上午上班: 正常YXX0004 2011-08-09 上午下班: 正常YXX0004 2011-08-09 下午上班: 正常YXX0004 2011-08-09 下午下班: 正常YXX0004 2011-08-10 上午上班: 正常YXX0004 2011-08-10 上午下班: 正常YXX0004 2011-08-10 下午上班: 正常YXX0004 2011-08-10 下午下班: 正常YXX0004 2011-08-11 上午上班: 正常YXX0004 2011-08-11 上午下班: 正常YXX0004 2011-08-11 下午上班: 正常YXX0004 2011-08-11 下午下班: 正常YXX0004 2011-08-12 上午上班: 正常YXX0004 2011-08-12 上午下班: 正常YXX0004 2011-08-12 下午上班: 正常YXX0004 2011-08-12 下午下班: 正常YXX0004 2011-08-14 上午上班: 正常YXX0004 2011-08-14 上午下班: 正常YXX0004 2011-08-14 下午上班: 未刷卡YXX0004 2011-08-14 下午下班: 正常YXX0004 2011-08-15 上午上班: 正常YXX0004 2011-08-15 上午下班: 正常YXX0004 2011-08-15 下午上班: 正常YXX0004 2011-08-15 下午下班: 正常YXX0004 2011-08-16 上午上班: 正常YXX0004 2011-08-16 上午下班: 正常YXX0004 2011-08-16 下午上班: 正常YXX0004 2011-08-16 下午下班: 正常YXX0004 2011-08-17 上午上班: 正常YXX0004 2011-08-17 上午下班: 正常YXX0004 2011-08-17 下午上班: 未刷卡YXX0004 2011-08-18 上午上班: 正常YXX0004 2011-08-18 上午下班: 正常YXX0004 2011-08-18 下午上班: 正常YXX0004 2011-08-18 下午下班: 正常YXX0004 2011-08-19 上午上班: 正常YXX0004 2011-08-19 上午下班: 正常YXX0004 2011-08-19 下午上班: 正常YXX0004 2011-08-19 下午下班: 正常YXX0004 2011-08-21 上午上班: 正常YXX0004 2011-08-21 上午下班: 正常YXX0004 2011-08-21 下午上班: 未刷卡YXX0004 2011-08-21 下午下班: 正常YXX0004 2011-08-22 上午上班: 正常YXX0004 2011-08-22 上午下班: 正常YXX0004 2011-08-22 下午上班: 正常YXX0004 2011-08-22 下午下班: 正常YXX0004 2011-08-23 上午上班: 正常YXX0004 2011-08-23 上午下班: 正常YXX0004 2011-08-23 下午上班: 正常YXX0004 2011-08-23 下午下班: 正常YXX0004 2011-08-24 上午上班: 正常YXX0004 2011-08-24 上午下班: 正常YXX0004 2011-08-24 下午上班: 正常YXX0004 2011-08-24 下午下班: 正常YXX0004 2011-08-25 上午上班: 正常YXX0004 2011-08-25 上午下班: 正常YXX0004 2011-08-25 下午上班: 正常YXX0004 2011-08-25 下午下班: 正常YXX0004 2011-08-26 上午上班: 正常YXX0004 2011-08-26 上午下班: 正常YXX0004 2011-08-26 下午上班: 正常YXX0004 2011-08-26 下午下班: 正常YXX0004 2011-08-28 上午上班: 正常YXX0004 2011-08-28 上午下班: 正常YXX0004 2011-08-28 下午上班: 未刷卡YXX0004 2011-08-29 上午上班: 正常YXX0004 2011-08-29 上午下班: 正常YXX0004 2011-08-29 下午上班: 正常YXX0004 2011-08-29 下午下班: 正常YXX0004 2011-08-30 上午上班: 正常YXX0004 2011-08-30 上午下班: 正常YXX0004 2011-08-30 下午上班: 正常YXX0004 2011-08-30 下午下班: 正常YXX0004 2011-08-31 上午上班: 正常YXX0004 2011-08-31 上午下班: 正常YXX0004 2011-08-31 下午上班: 正常YXX0004 2011-08-31 下午下班: 正常
[解决办法]
select a.emp,b.cdate,c.ctype+': '+case when cast(a.cardtime as datetime) between cast(c.KSTA as datetime) and cast(c.KLST as datetime) then '正常'when cast(a.cardtime as datetime)>cast(c.KLST as datetime) then '迟到'when cast(a.cardtime as datetime)<cast(c.KSTA as datetime) then '早退'else '未打卡' end 'ctype'from (select row_number() over(partition by cdate order by cardtime) rn,* from CardList) a inner join WorkDate b on a.emp=b.emp and a.cdate=b.cdateinner join BANCI c on b.banci=c.code and a.rn=c.itemwhere b.banci is not null emp cdate ctype-------------------- -------------------- ----------------------------YXX0004 2011-08-01 上午上班: 正常YXX0004 2011-08-01 上午下班: 正常YXX0004 2011-08-01 下午上班: 正常YXX0004 2011-08-01 下午下班: 正常YXX0004 2011-08-02 上午上班: 正常YXX0004 2011-08-02 上午下班: 正常YXX0004 2011-08-02 下午上班: 正常YXX0004 2011-08-03 上午上班: 正常YXX0004 2011-08-03 上午下班: 正常YXX0004 2011-08-03 下午上班: 正常YXX0004 2011-08-03 下午下班: 正常YXX0004 2011-08-04 上午上班: 正常YXX0004 2011-08-04 上午下班: 正常YXX0004 2011-08-04 下午上班: 正常YXX0004 2011-08-04 下午下班: 正常YXX0004 2011-08-05 上午上班: 正常YXX0004 2011-08-05 上午下班: 正常YXX0004 2011-08-05 下午上班: 正常YXX0004 2011-08-05 下午下班: 正常YXX0004 2011-08-07 上午上班: 正常YXX0004 2011-08-07 上午下班: 正常YXX0004 2011-08-07 下午上班: 早退YXX0004 2011-08-07 下午下班: 正常YXX0004 2011-08-08 上午上班: 正常YXX0004 2011-08-08 上午下班: 正常YXX0004 2011-08-08 下午上班: 正常YXX0004 2011-08-08 下午下班: 正常YXX0004 2011-08-09 上午上班: 正常YXX0004 2011-08-09 上午下班: 正常YXX0004 2011-08-09 下午上班: 正常YXX0004 2011-08-09 下午下班: 正常YXX0004 2011-08-10 上午上班: 正常YXX0004 2011-08-10 上午下班: 正常YXX0004 2011-08-10 下午上班: 正常YXX0004 2011-08-10 下午下班: 正常YXX0004 2011-08-11 上午上班: 正常YXX0004 2011-08-11 上午下班: 正常YXX0004 2011-08-11 下午上班: 正常YXX0004 2011-08-11 下午下班: 正常YXX0004 2011-08-12 上午上班: 正常YXX0004 2011-08-12 上午下班: 正常YXX0004 2011-08-12 下午上班: 正常YXX0004 2011-08-12 下午下班: 正常YXX0004 2011-08-14 上午上班: 正常YXX0004 2011-08-14 上午下班: 正常YXX0004 2011-08-14 下午上班: 早退YXX0004 2011-08-14 下午下班: 正常YXX0004 2011-08-15 上午上班: 正常YXX0004 2011-08-15 上午下班: 正常YXX0004 2011-08-15 下午上班: 正常YXX0004 2011-08-15 下午下班: 正常YXX0004 2011-08-16 上午上班: 正常YXX0004 2011-08-16 上午下班: 正常YXX0004 2011-08-16 下午上班: 正常YXX0004 2011-08-16 下午下班: 正常YXX0004 2011-08-17 上午上班: 正常YXX0004 2011-08-17 上午下班: 正常YXX0004 2011-08-17 下午上班: 迟到YXX0004 2011-08-18 上午上班: 正常YXX0004 2011-08-18 上午下班: 正常YXX0004 2011-08-18 下午上班: 正常YXX0004 2011-08-18 下午下班: 正常YXX0004 2011-08-19 上午上班: 正常YXX0004 2011-08-19 上午下班: 正常YXX0004 2011-08-19 下午上班: 正常YXX0004 2011-08-19 下午下班: 正常YXX0004 2011-08-21 上午上班: 正常YXX0004 2011-08-21 上午下班: 正常YXX0004 2011-08-21 下午上班: 早退YXX0004 2011-08-21 下午下班: 正常YXX0004 2011-08-22 上午上班: 正常YXX0004 2011-08-22 上午下班: 正常YXX0004 2011-08-22 下午上班: 正常YXX0004 2011-08-22 下午下班: 正常YXX0004 2011-08-23 上午上班: 正常YXX0004 2011-08-23 上午下班: 正常YXX0004 2011-08-23 下午上班: 正常YXX0004 2011-08-23 下午下班: 正常YXX0004 2011-08-24 上午上班: 正常YXX0004 2011-08-24 上午下班: 正常YXX0004 2011-08-24 下午上班: 正常YXX0004 2011-08-24 下午下班: 正常YXX0004 2011-08-25 上午上班: 正常YXX0004 2011-08-25 上午下班: 正常YXX0004 2011-08-25 下午上班: 正常YXX0004 2011-08-25 下午下班: 正常YXX0004 2011-08-26 上午上班: 正常YXX0004 2011-08-26 上午下班: 正常YXX0004 2011-08-26 下午上班: 正常YXX0004 2011-08-26 下午下班: 正常YXX0004 2011-08-28 上午上班: 正常YXX0004 2011-08-28 上午下班: 正常YXX0004 2011-08-28 下午上班: 迟到YXX0004 2011-08-29 上午上班: 正常YXX0004 2011-08-29 上午下班: 正常YXX0004 2011-08-29 下午上班: 正常YXX0004 2011-08-29 下午下班: 正常YXX0004 2011-08-30 上午上班: 正常YXX0004 2011-08-30 上午下班: 正常YXX0004 2011-08-30 下午上班: 正常YXX0004 2011-08-30 下午下班: 正常YXX0004 2011-08-31 上午上班: 正常YXX0004 2011-08-31 上午下班: 正常YXX0004 2011-08-31 下午上班: 正常YXX0004 2011-08-31 下午下班: 正常
[解决办法]
USE tempdbgoWITH aAS(SELECT a.[Emp], a.[Banci], a.CDate,-- b.[KSTA] AS [KSTA],-- c.CardTime, 打卡状态=case when CAST(c.[CardTime] AS DATETIME)<=[KTIME] and right(b.Ctype,2)=N'上班' then N'正常' when CAST(c.[CardTime] AS DATETIME)>[KTIME] and right(b.Ctype,2)=N'上班' then N'迟到' when CAST(c.[CardTime] AS DATETIME)>=[KTIME] and right(b.Ctype,2)=N'下班' then N'正常' when CAST(c.[CardTime] AS DATETIME)<[KTIME] and right(b.Ctype,2)=N'下班' then N'早退' else N'未打卡' end, b.CtypeFROM [WorkDate] AS a INNER JOIN [BANCI] AS b ON a.[Banci]=b.[Code] LEFT JOIN [CardList] AS c ON c.Emp=a.Emp AND c.CDate=a.CDate AND CAST(c.[CardTime] AS DATETIME) BETWEEN b.[KSTA] AND b.[KLST])SELECT *FROM aPIVOT (MAX(打卡状态) FOR Ctype IN(上午上班,上午下班,下午上班,下午下班,加班上班,加班下班)) AS b /*Emp Banci CDate 上午上班 上午下班 下午上班 下午下班 加班上班 加班下班YXX0004 10 2011-08-01 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-02 迟到 正常 正常 未打卡 未打卡 未打卡YXX0004 10 2011-08-03 迟到 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-04 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-05 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-07 迟到 正常 未打卡 正常 未打卡 未打卡YXX0004 10 2011-08-08 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-09 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-10 迟到 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-11 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-12 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-14 正常 正常 未打卡 正常 未打卡 未打卡YXX0004 10 2011-08-15 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-16 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-17 迟到 正常 未打卡 正常 未打卡 未打卡YXX0004 10 2011-08-18 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-19 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-21 正常 正常 未打卡 正常 未打卡 未打卡YXX0004 10 2011-08-22 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-23 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-24 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-25 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-26 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-28 正常 正常 未打卡 正常 未打卡 未打卡YXX0004 10 2011-08-29 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-30 正常 正常 正常 正常 未打卡 未打卡YXX0004 10 2011-08-31 正常 正常 正常 正常 未打卡 未打卡*/