考勤機的紀錄表
卡號, 時間
A0001, 2018/3/16 22:03:05
A0001, 2018/3/16 14:20:10
A0001, 2018/3/16 03:05:33
A0001, 2018/3/15 14:07:30
A0001, 2018/3/15 14:05:15
A0001, 2018/3/14 21:09:30
A0001, 2018/3/14 13:50:15
SQL要如何下才會出現我要的結果?
卡號, 刷進 ,刷退
A0001, 2018/3/16 14:20:10 ,2018/3/16 22:03:05
A0001, 2018/3/15 14:05:15 ,2018/3/16 03:05:33
A0001, 2018/3/14 13:50:15 ,2018/3/14 21:09:30
ps.上班時間為14:00~22:00為正常班,有效打卡以13:00為間隔一日判斷
解答:
感覺好玩的題目
我這邊先用本土煉鋼方式(沒考慮效能版本),一步一步分解來組合出你的SQL
【未優化版本】https://goo.gl/3uJKsN
【優化版本】https://goo.gl/oWgztn
--【以下建立測試資料數據】
create table #Tem_Table ([USERID] nvarchar(10),[Datetime] datetime );
insert into #Tem_Table ([USERID],[Datetime]) values
('A0001','2018/3/16 22:03:05')
,('A0001','2018/3/16 03:05:33')
,('A0001','2018/3/15 14:07:30')
,('A0001','2018/3/15 14:05:15')
,('A0001','2018/3/14 21:09:30')
,('A0001','2018/3/14 13:50:15')
,('A0002','2018/3/14 21:09:30')
,('A0002','2018/3/14 13:50:15')
;
--【開始拼接你要的打卡紀錄】
select
[USERID] 卡號
,min([datetime]) 刷進 --取最小排名得 "刷進"
,max([datetime]) 刷出 --取最大排名得 "刷出"
from #Tem_Table
group BY CONVERT(CHAR(8), dateadd (hour,-13,[datetime]), 112) --減十三小時
,[USERID] --這邊要分組人要不然會資料錯亂
主要要能夠區分時間區段,而公司比較特別不是以半夜00:00來區分
假如是00:00可以用天來分組很方便。
但這邊就反向思考一下,只要把所有時間都減上13小時
其實就可以照著00:00的方式來分組
以時間(不包含時分秒)分組,
並依實際日期取其min(日期)得到刷進,並取其max(日期)得到刷退