原问题:
--打卡记录表CREATE TABLE OriginalData([id] int IDENTITY(1,1),EmployeeID int,CheckTime datetime)INSERT INTO OriginalDataSELECT 1,'2007-06-11 08:01' UNION ALLSELECT 1,'2007-06-11 12:02' UNION ALLSELECT 1,'2007-06-11 13:05' UNION ALLSELECT 1,'2007-06-11 17:40' UNION ALLSELECT 1,'2007-06-11 19:00' UNION ALLSELECT 1,'2007-06-11 23:42' UNION ALLSELECT 1,'2007-06-11 23:58' UNION ALLSELECT 1,'2007-06-12 07:50' UNION ALLSELECT 1,'2007-06-12 12:00' UNION ALLSELECT 3,'2007-06-11 20:00' UNION ALLSELECT 3,'2007-06-12 04:00' UNION ALLSELECT 3,'2007-06-12 07:55' UNION ALLSELECT 3,'2007-06-12 12:00' UNION ALLSELECT 3,'2007-06-12 13:00' UNION ALLSELECT 3,'2007-06-12 17:35' --考勤表CREATE TABLE OnOffDutyData(EmployeeID int,CheckDate datetime
,OnDuty1 datetime,OffDuty1 datetime
,OnDuty2 datetime,OffDuty2 datetime
,OnDuty3 datetime,OffDuty3 datetime
,OnDuty4 datetime,OffDuty4 datetime)INSERT INTO OnOffDutyData (EmployeeID,CheckDate)SELECT 1,'2007-06-11' UNION ALLSELECT 1,'2007-06-12' UNION ALLSELECT 3,'2007-06-11' UNION ALLSELECT 3,'2007-06-12'
SELECT * FROM OriginalDataSELECT * FROM OnOffDutyData/*
想要的初始化结果:
EmployeeID CheckDate OnDuty1 OffDuty1 OnDuty2 OffDuty2 OnDuty3 OffDuty3 OnDuty4
1 2007-06-11 08:01 12:02 13:05 17:40 19:00 23:42 07:50 --(07:50为第2天的第一次打卡记录)
1 2007-06-12 07:50 12:00 NULL NULL NULL NULL NULL
3 2007-06-11 20:00 04:00 (04:00 为第2天第1次打卡,其他段为如上行为NULL)
4 2007-06-12 04:00 07:55 12:00 13:00 17:35 NULL NULL
--方法说明:
按EmployeeID 和 打卡日期 CONVERT(nchar(10),CheckTime,120) ,每天提取当天前6次打卡记录和第2天第一次打卡记录
UPDATE 考勤表(OnOffDutyData)。
打卡记录表数据大小:5000(人)×30(天)×6(大约每天的打卡次数)=90万条记录
考勤表数据大小:5000(人)×30(天)=15万条记录
要求一个能提高效率的Update方法,具体实现方法不限。*/
DROP TABLE OriginalData,OnOffDutyData
解决方法参考:
方法1,来自leo_lesley(leo) :
,OnDuty1 datetime,OffDuty1 datetime
,OnDuty2 datetime,OffDuty2 datetime
,OnDuty3 datetime,OffDuty3 datetime
,OnDuty4 datetime,OffDuty4 datetime)INSERT INTO OnOffDutyData (EmployeeID,CheckDate)SELECT 1,'2007-06-11' UNION ALLSELECT 1,'2007-06-12' UNION ALLSELECT 3,'2007-06-11' UNION ALLSELECT 3,'2007-06-12'
SELECT * FROM OriginalDataSELECT * FROM OnOffDutyData/*
想要的初始化结果:
EmployeeID CheckDate OnDuty1 OffDuty1 OnDuty2 OffDuty2 OnDuty3 OffDuty3 OnDuty4
1 2007-06-11 08:01 12:02 13:05 17:40 19:00 23:42 07:50 --(07:50为第2天的第一次打卡记录)
1 2007-06-12 07:50 12:00 NULL NULL NULL NULL NULL
3 2007-06-11 20:00 04:00 (04:00 为第2天第1次打卡,其他段为如上行为NULL)
4 2007-06-12 04:00 07:55 12:00 13:00 17:35 NULL NULL
--方法说明:
按EmployeeID 和 打卡日期 CONVERT(nchar(10),CheckTime,120) ,每天提取当天前6次打卡记录和第2天第一次打卡记录
UPDATE 考勤表(OnOffDutyData)。
打卡记录表数据大小:5000(人)×30(天)×6(大约每天的打卡次数)=90万条记录
考勤表数据大小:5000(人)×30(天)=15万条记录
要求一个能提高效率的Update方法,具体实现方法不限。*/
DROP TABLE OriginalData,OnOffDutyData
解决方法参考:
方法1,来自leo_lesley(leo) :
------------看看这个用的是两个表变量,然后直接update处理的,不用先删除,再插入。
--打卡记录表CREATE TABLE OriginalData([id] int IDENTITY(1,1),EmployeeID int,CheckTime datetime)INSERT INTO OriginalDataSELECT 1,'2007-06-11 08:01' UNION ALLSELECT 1,'2007-06-11 12:02' UNION ALLSELECT 1,'2007-06-11 13:05' UNION ALLSELECT 1,'2007-06-11 17:40' UNION ALLSELECT 1,'2007-06-11 19:00' UNION ALLSELECT 1,'2007-06-11 23:42' UNION ALLSELECT 1,'2007-06-11 23:58' UNION ALLSELECT 1,'2007-06-12 07:50' UNION ALLSELECT 1,'2007-06-12 12:00' UNION ALLSELECT 3,'2007-06-11 20:00' UNION ALLSELECT 3,'2007-06-12 04:00' UNION ALLSELECT 3,'2007-06-12 07:55' UNION ALLSELECT 3,'2007-06-12 12:00' UNION ALLSELECT 3,'2007-06-12 13:00' UNION ALLSELECT 3,'2007-06-12 17:35'
go
--考勤表CREATE TABLE OnOffDutyData(EmployeeID int,CheckDate datetime
,OnDuty1 datetime,OffDuty1 datetime
,OnDuty2 datetime,OffDuty2 datetime
,OnDuty3 datetime,OffDuty3 datetime
,OnDuty4 datetime,OffDuty4 datetime)INSERT INTO OnOffDutyData (EmployeeID,CheckDate)SELECT 1,'2007-06-11' UNION ALLSELECT 1,'2007-06-12' UNION ALLSELECT 3,'2007-06-11' UNION ALLSELECT 3,'2007-06-12'
go
declare @t table(EmployeeID int,CheckDate datetime,OnDuty1 varchar(10),OnDuty2 varchar(10),OnDuty3 varchar(10),OnDuty4 varchar(10),OnDuty5 varchar(10),OnDuty6 varchar(10),OnDuty7 varchar(10),OnDuty8 varchar(10))declare @lsb table(EmployeeID int,d datetime,m varchar(10),cnt int)
insert @lsbSELECT b.EmployeeID,d=convert(char(10),b.CheckTime,21),m=right(convert(char(16),b.CheckTime,21),5),
Cnt=(select count(1) from OriginalData where EmployeeID=b.EmployeeID and convert(char(10),b.CheckTime,21)=convert(char(10),CheckTime,21) and CheckTime<b.CheckTime )FROM OriginalData b
insert @tSELECT a.EmployeeID,CheckDate=convert(char(10),a.CheckDate,21),
OnDuty1=max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 0 then m else null end),
OnDuty1=isnull(max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 1 then m end),min(case when a.EmployeeID=b.EmployeeID and cnt = 0 and convert(char(10),a.CheckDate,21)<d then m end)),
OnDuty2=max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 2 then m else null end),
OnDuty2=isnull(max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 3 then m end),min(case when a.EmployeeID=b.EmployeeID and cnt = 0 and convert(char(10),a.CheckDate,21)<d then m end)),
OnDuty3=max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 4 then m else null end),
OnDuty3=isnull(max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 5 then m end),min(case when a.EmployeeID=b.EmployeeID and cnt = 0 and convert(char(10),a.CheckDate,21)<d then m end)),
OnDuty4=max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 6 then m else null end),
OnDuty4=isnull(max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 7 then m end),min(case when a.EmployeeID=b.EmployeeID and cnt = 0 and convert(char(10),a.CheckDate,21)<d then m end))FROM OnOffDutyData a left join @lsb b on a.EmployeeID=b.EmployeeIDgroup by a.EmployeeID,CheckDateorder by a.EmployeeID,CheckDate
updatea set a.OnDuty1=t.CheckDate+t.OnDuty1,
a.OffDuty1=case when t.OnDuty1 is not null then t.CheckDate+t.OnDuty2 else null end,
a.OnDuty2=t.CheckDate+t.OnDuty3,
a.OffDuty2=case when t.OnDuty3 is not null then t.CheckDate+t.OnDuty4 else null end,
a.OnDuty3=t.CheckDate+t.OnDuty5,
a.OffDuty3=case when t.OnDuty5 is not null then t.CheckDate+t.OnDuty6 else null end,
a.OnDuty4=t.CheckDate+t.OnDuty7,
a.OffDuty4=case when t.OnDuty7 is not null then t.CheckDate+t.OnDuty8 else null endfrom OnOffDutyData a,@t twhere a.EmployeeID=t.EmployeeID and a.CheckDate=t.CheckDate
select * from OnOffDutyData
drop table OnOffDutyData,OriginalData
方法2,来自hellowork(一两清风):
--打卡记录表CREATE TABLE OriginalData([id] int IDENTITY(1,1),EmployeeID int,CheckTime datetime)INSERT INTO OriginalDataSELECT 1,'2007-06-11 08:01' UNION ALLSELECT 1,'2007-06-11 12:02' UNION ALLSELECT 1,'2007-06-11 13:05' UNION ALLSELECT 1,'2007-06-11 17:40' UNION ALLSELECT 1,'2007-06-11 19:00' UNION ALLSELECT 1,'2007-06-11 23:42' UNION ALLSELECT 1,'2007-06-11 23:58' UNION ALLSELECT 1,'2007-06-12 07:50' UNION ALLSELECT 1,'2007-06-12 12:00' UNION ALLSELECT 3,'2007-06-11 20:00' UNION ALLSELECT 3,'2007-06-12 04:00' UNION ALLSELECT 3,'2007-06-12 07:55' UNION ALLSELECT 3,'2007-06-12 12:00' UNION ALLSELECT 3,'2007-06-12 13:00' UNION ALLSELECT 3,'2007-06-12 17:35'
go
--考勤表CREATE TABLE OnOffDutyData(EmployeeID int,CheckDate datetime
,OnDuty1 datetime,OffDuty1 datetime
,OnDuty2 datetime,OffDuty2 datetime
,OnDuty3 datetime,OffDuty3 datetime
,OnDuty4 datetime,OffDuty4 datetime)INSERT INTO OnOffDutyData (EmployeeID,CheckDate)SELECT 1,'2007-06-11' UNION ALLSELECT 1,'2007-06-12' UNION ALLSELECT 3,'2007-06-11' UNION ALLSELECT 3,'2007-06-12'
go
declare @t table(EmployeeID int,CheckDate datetime,OnDuty1 varchar(10),OnDuty2 varchar(10),OnDuty3 varchar(10),OnDuty4 varchar(10),OnDuty5 varchar(10),OnDuty6 varchar(10),OnDuty7 varchar(10),OnDuty8 varchar(10))declare @lsb table(EmployeeID int,d datetime,m varchar(10),cnt int)
insert @lsbSELECT b.EmployeeID,d=convert(char(10),b.CheckTime,21),m=right(convert(char(16),b.CheckTime,21),5),
Cnt=(select count(1) from OriginalData where EmployeeID=b.EmployeeID and convert(char(10),b.CheckTime,21)=convert(char(10),CheckTime,21) and CheckTime<b.CheckTime )FROM OriginalData b
insert @tSELECT a.EmployeeID,CheckDate=convert(char(10),a.CheckDate,21),
OnDuty1=max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 0 then m else null end),
OnDuty1=isnull(max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 1 then m end),min(case when a.EmployeeID=b.EmployeeID and cnt = 0 and convert(char(10),a.CheckDate,21)<d then m end)),
OnDuty2=max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 2 then m else null end),
OnDuty2=isnull(max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 3 then m end),min(case when a.EmployeeID=b.EmployeeID and cnt = 0 and convert(char(10),a.CheckDate,21)<d then m end)),
OnDuty3=max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 4 then m else null end),
OnDuty3=isnull(max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 5 then m end),min(case when a.EmployeeID=b.EmployeeID and cnt = 0 and convert(char(10),a.CheckDate,21)<d then m end)),
OnDuty4=max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 6 then m else null end),
OnDuty4=isnull(max(case when a.EmployeeID=b.EmployeeID and convert(char(10),a.CheckDate,21)=d and cnt = 7 then m end),min(case when a.EmployeeID=b.EmployeeID and cnt = 0 and convert(char(10),a.CheckDate,21)<d then m end))FROM OnOffDutyData a left join @lsb b on a.EmployeeID=b.EmployeeIDgroup by a.EmployeeID,CheckDateorder by a.EmployeeID,CheckDate
updatea set a.OnDuty1=t.CheckDate+t.OnDuty1,
a.OffDuty1=case when t.OnDuty1 is not null then t.CheckDate+t.OnDuty2 else null end,
a.OnDuty2=t.CheckDate+t.OnDuty3,
a.OffDuty2=case when t.OnDuty3 is not null then t.CheckDate+t.OnDuty4 else null end,
a.OnDuty3=t.CheckDate+t.OnDuty5,
a.OffDuty3=case when t.OnDuty5 is not null then t.CheckDate+t.OnDuty6 else null end,
a.OnDuty4=t.CheckDate+t.OnDuty7,
a.OffDuty4=case when t.OnDuty7 is not null then t.CheckDate+t.OnDuty8 else null endfrom OnOffDutyData a,@t twhere a.EmployeeID=t.EmployeeID and a.CheckDate=t.CheckDate
select * from OnOffDutyData
drop table OnOffDutyData,OriginalData
方法2,来自hellowork(一两清风):
--打卡记录表CREATE TABLE OriginalData([id] int IDENTITY(1,1),EmployeeID int,CheckTime datetime)INSERT INTO OriginalDataSELECT 1,'2007-06-11 08:01' UNION ALLSELECT 1,'2007-06-11 12:02' UNION ALLSELECT 1,'2007-06-11 13:05' UNION ALLSELECT 1,'2007-06-11 17:40' UNION ALLSELECT 1,'2007-06-11 19:00' UNION ALLSELECT 1,'2007-06-11 23:42' UNION ALL --没有这句子,结果的第一行记录就有问题,无法记录第2天的第1次刷卡记录SELECT 1,'2007-06-11 23:58' UNION ALLSELECT 1,'2007-06-12 07:50' UNION ALLSELECT 1,'2007-06-12 12:00' UNION ALLSELECT 3,'2007-06-11 20:00' UNION ALLSELECT 3,'2007-06-12 04:00' UNION ALLSELECT 3,'2007-06-12 07:55' UNION ALLSELECT 3,'2007-06-12 12:00' UNION ALLSELECT 3,'2007-06-12 13:00' UNION ALLSELECT 3,'2007-06-12 17:35'
go
--考勤表CREATE TABLE OnOffDutyData(EmployeeID int,CheckDate datetime
,OnDuty1 datetime,OffDuty1 datetime
,OnDuty2 datetime,OffDuty2 datetime
,OnDuty3 datetime,OffDuty3 datetime
,OnDuty4 datetime,OffDuty4 datetime)INSERT INTO OnOffDutyData (EmployeeID,CheckDate)SELECT 1,'2007-06-11' UNION ALLSELECT 1,'2007-06-12' UNION ALLSELECT 3,'2007-06-11' UNION ALLSELECT 3,'2007-06-12'
go
SELECT EmployeeID,CheckTime,
OnDuty1=max(OnDuty1),
OnOffDuty1=ISNULL(max(OnOffDuty1),max(OnDuty4)),
OnDuty2=case when max(OnOffDuty1) is null then NULL else ISNULL(max(OnDuty2),max(OnDuty4)) end,
OnOffDuty2=case when max(OnDuty2) is null then NULL else ISNULL(max(OnOffDuty2),max(OnDuty4)) end,
OnDuty3=case when max(OnOffDuty2) is null then NULL else ISNULL(max(OnDuty3),max(OnDuty4)) end,
OnOffDuty3=case when max(OnDuty3) is null then NULL else ISNULL(max(OnOffDuty3),max(OnDuty4)) end,
OnDuty4=case when max(OnOffDuty3) is null then NULL else max(OnDuty4) endFROM
(select EmployeeID,CheckTime=convert(varchar(10),CheckTime,120),
OnDuty1=(select top 1 convert(varchar(5),CheckTime,108) from OriginalData where EmployeeID = t.EmployeeID and datediff(dd,CheckTime,t.CheckTime) = 0 order by CheckTime),
OnOffDuty1=(select convert(varchar(5),CheckTime,108) from OriginalData as a where EmployeeID = t.EmployeeID and
go
--考勤表CREATE TABLE OnOffDutyData(EmployeeID int,CheckDate datetime
,OnDuty1 datetime,OffDuty1 datetime
,OnDuty2 datetime,OffDuty2 datetime
,OnDuty3 datetime,OffDuty3 datetime
,OnDuty4 datetime,OffDuty4 datetime)INSERT INTO OnOffDutyData (EmployeeID,CheckDate)SELECT 1,'2007-06-11' UNION ALLSELECT 1,'2007-06-12' UNION ALLSELECT 3,'2007-06-11' UNION ALLSELECT 3,'2007-06-12'
go
SELECT EmployeeID,CheckTime,
OnDuty1=max(OnDuty1),
OnOffDuty1=ISNULL(max(OnOffDuty1),max(OnDuty4)),
OnDuty2=case when max(OnOffDuty1) is null then NULL else ISNULL(max(OnDuty2),max(OnDuty4)) end,
OnOffDuty2=case when max(OnDuty2) is null then NULL else ISNULL(max(OnOffDuty2),max(OnDuty4)) end,
OnDuty3=case when max(OnOffDuty2) is null then NULL else ISNULL(max(OnDuty3),max(OnDuty4)) end,
OnOffDuty3=case when max(OnDuty3) is null then NULL else ISNULL(max(OnOffDuty3),max(OnDuty4)) end,
OnDuty4=case when max(OnOffDuty3) is null then NULL else max(OnDuty4) endFROM
(select EmployeeID,CheckTime=convert(varchar(10),CheckTime,120),
OnDuty1=(select top 1 convert(varchar(5),CheckTime,108) from OriginalData where EmployeeID = t.EmployeeID and datediff(dd,CheckTime,t.CheckTime) = 0 order by CheckTime),
OnOffDuty1=(select convert(varchar(5),CheckTime,108) from OriginalData as a where EmployeeID = t.EmployeeID and
编辑推荐:
- 处理考勤打卡记录问题03-02
- 获取SQL Server数据库里表的占用容量大小03-02
- 生成1千万个随机串号9位英文字母03-02
- SQL Server的有效安装03-02
- 实战JBuilder7+WebLogic7存取MS SQL Server200003-02
- 四项技术提高SQL Server性能03-02
- sqlserver 2000h 和 jdbc 的融合问题03-02
- SQL Server补丁版本的检查和安装过程中常见问题03-02
下一篇:
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- 亚马逊 AWS 云计算部门阿联酋数据中心遭撞击起火,涉事可用区服务正逐步恢复
- IT早报 0302:2026 年 2 月汽车销量榜出炉;荣耀机器人手机 Robot Phone 亮相;多地试点开征新能源汽车“里程税”不实;业内人士回应重新激活魅族需要多少钱...
- 荣耀首款人形机器人亮相 MWC 2026,现场表演舞蹈及后空翻
荣耀首款人形机器人亮相 MWC 2026,现场表演舞蹈及后空翻
26-03-02 - 万志强:魅族 23 已完成开发但不会推向市场,后续 Flyme 仍提供基本维护
- 消息称卡普空将明年评估《生化危机》系列游戏用户反响,影响新作方向
消息称卡普空将明年评估《生化危机》系列游戏用户反响,影响新作方向
26-03-01 - M 站(Metacritic)表态:绝不允许 AI 生成评测进入平台
M 站(Metacritic)表态:绝不允许 AI 生成评测进入平台
26-03-01 - 荣耀 CEO 李健提出 Augmented Human Intelligence 理念:让 AI 既有 IQ 又有 EQ
- 比亚迪 2 月新能源汽车销量 190,190 辆,乘用车 187,782 辆
- 国服上线至今 157 天,太空飞船协作夺宝游戏《无主星渊》宣布 4 月停运
- 《GTA 6》PlayStation 预购页面已在准备中,120 美元传闻待验证
