考勤問題思路和解決

2021-09-07 13:17:58 字數 4555 閱讀 7925

近期在做乙個考勤系統,考勤主要關注的是缺勤、遲到和早退。眼下的打卡控制器能夠記錄username和打卡時間,使用者可能一天打卡多次,也可能一天僅僅打了一次卡,這些情況都須要考慮。

打卡資訊都儲存在考勤表中,從中要挖掘出乙個月內的缺勤人員,遲到人員和早退人員,而且能顯示缺勤、遲到和早退的時間。

考勤表

create table [dbo].[kaoqin](

[user_name] [varchar](50) null,

[card_time] [datetime] null

) on [primary]

go

插入測試資料

insert into [master].[dbo].[kaoqin]

select '張三', '2014-08-03 09:36:00'

union all

select '張三', '2014-08-03 18:10:00'

union all

select '張三', '2014-08-04 08:32:00'

union all

select '張三', '2014-08-04 15:15:00'

union all

select '張三', '2014-08-05 09:32:00'

union all

select '張三', '2014-08-05 15:15:00'

union all

select '張三', '2014-08-01 08:36:00'

union all

select '張三', '2014-08-01 18:10:00'

union all

select '張三', '2014-08-02 08:32:00'

union all

select '張三', '2014-08-02 18:15:00'

union all

select '張三', '2014-08-25 08:00:00'

union all

select '張三', '2014-08-24 19:00:00'

union all

select '張三', '2014-08-27 08:00:00'

union all

select '張三', '2014-08-27 17:00:00'

union all

select '張三', '2014-08-26 10:00:00'

union all

select '張三', '2014-08-26 18:30:00'

union all

select '張三', '2014-08-26 8:00:00'

union all

select '張三', '2014-08-27 18:56:00'

go

我的思路是用一張暫時表得到這個月的全部工作日。將該暫時表與使用者進行交叉連線。這樣每乙個使用者在這個月的每乙個工作日都有一條記錄。

如果早上9點為上班時間,18點為下班時間,這個能夠興許做成變數的形式。

declare @time_start datetime

declare @time_end datetime

set @time_start = '2014-08-01 00:00:00'

set @time_end = dateadd(m,1,@time_start)

-- 乙個月的工作日

if object_id('tempdb..#tempdate') is not null

begin

drop table #tempdate

endcreate table #tempdate

( stat_day varchar(10)

)if object_id('tempdb..#tempuserdate') is not null

begin

drop table #tempuserdate

endcreate table #tempuserdate(

stat_day varchar(10),

[user_name] varchar(40)

)create clustered index tempuserdate_index1 on #tempuserdate ([user_name],stat_day)

declare @time_temp datetime

set @time_temp = @time_start

while @time_temp < @time_end

begin

if datepart(weekday,@time_temp)>1 and datepart(weekday,@time_temp)<7

begin

insert into #tempdate (stat_day) values (convert(varchar(10),@time_temp,121))

endset @time_temp= dateadd(d,1,@time_temp)

endinsert into #tempuserdate

select * from #tempdate cross join

(select distinct [user_name] from [kaoqin]) t

從原始的kaoqin表中查詢出每乙個使用者的上班時間和下班時間。假設使用者一天的開啟記錄超過兩條。那麼就會取最早和最晚的一條分別作為上班時間和下班時間。

select [user_name],convert(varchar(10),card_time,121) as stat_day,

min(card_time) as on_time,max(card_time) as off_time from [kaoqin]

group by [user_name],convert(varchar(10),card_time,121)

通過暫時表#tempuserdate和上面的查詢結果關聯,假設左聯接為空,則證明該人員缺勤。

--缺勤

select * from #tempuserdate a

left join

( select [user_name],convert(varchar(10),card_time,121) as stat_day,

min(card_time) as on_time,max(card_time) as off_time from [kaoqin]

group by [user_name],convert(varchar(10),card_time,121)

) b on a.[user_name]=b.[user_name] and a.stat_day=b.stat_day

where [b].[user_name] is null

以下是遲到和早退的實現sql。

--遲到

select * from #tempuserdate a

left join

( select [user_name],convert(varchar(10),card_time,121) as stat_day,

min(card_time) as on_time,max(card_time) as off_time from [kaoqin]

group by [user_name],convert(varchar(10),card_time,121)

) b on a.[user_name]=b.[user_name] and a.stat_day=b.stat_day

where convert(varchar(100), [b].[on_time], 8)>'09:00:00'

--早退

select * from #tempuserdate a

left join

( select [user_name],convert(varchar(10),card_time,121) as stat_day,

min(card_time) as on_time,max(card_time) as off_time from [kaoqin]

group by [user_name],convert(varchar(10),card_time,121)

) b on a.[user_name]=b.[user_name] and a.stat_day=b.stat_day

where convert(varchar(100), [b].[off_time], 8)

得到的結果

假設某個人他今天既遲到又早退在終於的結果中都會體現。能夠從2014-08-05這條資料看出。當然,這個考勤系統還不完好,比如沒有將節日考慮進來,初步的考慮是採用job定期儲存每年的節日,假設員工請假,也須要納入到系統的考慮中。

Redis 做快取常見問題和解決思路

概念 大量查詢不存在的key,短時間內對db造成巨大的查詢壓力。解決方案 1 布隆過濾 將存在的key置於bitmap中,訪問db之前過濾請求 2 將不存在的key,以空值的形式儲存在cache中,減少對底層db的壓力。3 資料庫限流 概念 熱點key過期,在短時間內對db造成的巨大壓力。解決思路 ...

常見的反爬手段和解決思路

誤傷 在反爬蟲的過程中,錯誤的將普通使用者識別為爬蟲。誤傷率高的反爬蟲策略,效果再好也不能用。攔截 成功地阻止爬蟲訪問。這裡會有攔截率的概念。通常來說,攔截率越高的反爬蟲策略,誤傷的可能性就越高,因此需要做個權衡。資源 機器成本與人力成本的總和。1 通過headers欄位來反爬headers中有很多...

解決問題的思路

乙個if else 體現出的解決問題的能力,思路,這就是錢 string tostation string jobj data i agv target place code string mocode string jobj data i mo code 工單 task.receive date ...