计算时间间隔求助

x0y1z2 2010-03-24 10:15:43
create table 业务表(
pk varchar(10) primary key,
userid varchar(10) not null,
starttime datetime not null,
endtime datetime
);

create table 假期表(
pk int primary key,
userid varchar(10) not null,
starttime datetime not null,
endtime datetime not null
)

业务表存放业务数据,
假期表存放节假日、年假、病假(不包括周六周日),不包括本来就是周六周日的 节假日

现在要求每条业务数据从开始到结束的扣除假期表记录,扣除周六周日的小时数,
业务表中endtime没有的话取当前时间,
假期表中如果一条数据不是整天的话 小于4小时 按 实际小时数计算,超过4小时按24小时计算
周六、周日 按24小时计算
最后结果不是整小时的话用去尾法

DB是ms sqlserver 2000
如果要用到 视图、存储过程、函数、自定义类型 都可以,触发器不可以用

谢谢,觉得有点难度 :(
...全文
92 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
x0y1z2 2010-03-24
  • 打赏
  • 举报
回复
谢谢各位
上面的都是工作日,我要工作小时数,不过改了改 基本解决
dawugui 2010-03-24
  • 打赏
  • 举报
回复

--工作日处理函数(标准节假日)
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDay]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_WorkDay]
GO

--计算两个日期相差的工作天数
CREATE FUNCTION f_WorkDay(
@dt_begin datetime, --计算的开始日期
@dt_end datetime --计算的结束日期
)RETURNS int
AS
BEGIN
DECLARE @workday int,@i int,@bz bit,@dt datetime
IF @dt_begin>@dt_end
SELECT @bz=1,@dt=@dt_begin,@dt_begin=@dt_end,@dt_end=@dt
ELSE
SET @bz=0
SELECT @i=DATEDIFF(Day,@dt_begin,@dt_end)+1,
@workday=@i/7*5,
@dt_begin=DATEADD(Day,@i/7*7,@dt_begin)
WHILE @dt_begin<=@dt_end
BEGIN
SELECT @workday=CASE
WHEN (@@DATEFIRST+DATEPART(Weekday,@dt_begin)-1)%7 BETWEEN 1 AND 5
THEN @workday+1 ELSE @workday END,
@dt_begin=@dt_begin+1
END
RETURN(CASE WHEN @bz=1 THEN -@workday ELSE @workday END)
END
GO



/*=================================================================*/

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDayADD]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_WorkDayADD]
GO

--在指定日期上,增加指定工作天数后的日期
CREATE FUNCTION f_WorkDayADD(
@date datetime, --基础日期
@workday int --要增加的工作日数
)RETURNS datetime
AS
BEGIN
DECLARE @bz int
--增加整周的天数
SELECT @bz=CASE WHEN @workday<0 THEN -1 ELSE 1 END
,@date=DATEADD(Week,@workday/5,@date)
,@workday=@workday%5
--增加不是整周的工作天数
WHILE @workday<>0
SELECT @date=DATEADD(Day,@bz,@date),
@workday=CASE WHEN (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 BETWEEN 1 AND 5
THEN @workday-@bz ELSE @workday END
--避免处理后的日期停留在非工作日上
WHILE (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 in(0,6)
SET @date=DATEADD(Day,@bz,@date)
RETURN(@date)
END



--工作日处理函数(自定义节假日)
--工作日处理函数(自定义节假日)

if exists (select * from dbo.sysobjects where id = object_id(N'[tb_Holiday]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [tb_Holiday]
GO

--定义节假日表
CREATE TABLE tb_Holiday(
HDate smalldatetime primary key clustered, --节假日期
Name nvarchar(50) not null) --假日名称
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDay]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_WorkDay]
GO

--计算两个日期之间的工作天数
CREATE FUNCTION f_WorkDay(
@dt_begin datetime, --计算的开始日期
@dt_end datetime --计算的结束日期
)RETURNS int
AS
BEGIN
IF @dt_begin>@dt_end
RETURN(DATEDIFF(Day,@dt_begin,@dt_end)
+1-(
SELECT COUNT(*) FROM tb_Holiday
WHERE HDate BETWEEN @dt_begin AND @dt_end))
RETURN(-(DATEDIFF(Day,@dt_end,@dt_begin)
+1-(
SELECT COUNT(*) FROM tb_Holiday
WHERE HDate BETWEEN @dt_end AND @dt_begin)))
END
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDayADD]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_WorkDayADD]
GO

--在指定日期上增加工作天数
CREATE FUNCTION f_WorkDayADD(
@date datetime, --基础日期
@workday int --要增加的工作日数
)RETURNS datetime
AS
BEGIN
IF @workday>0
WHILE @workday>0
SELECT @date=@date+@workday,@workday=count(*)
FROM tb_Holiday
WHERE HDate BETWEEN @date AND @date+@workday
ELSE
WHILE @workday<0
SELECT @date=@date+@workday,@workday=-count(*)
FROM tb_Holiday
WHERE HDate BETWEEN @date AND @date+@workday
RETURN(@date)
END
--小F-- 2010-03-24
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 x0y1z2 的回复:]
真快,才一会儿就这么多回复了,我先研究下ls的,然后找精华贴
[/Quote]

就是老大的那个
x0y1z2 2010-03-24
  • 打赏
  • 举报
回复
真快,才一会儿就这么多回复了,我先研究下ls的,然后找精华贴
永生天地 2010-03-24
  • 打赏
  • 举报
回复
忘了写output参数了
永生天地 2010-03-24
  • 打赏
  • 举报
回复
没测试

create proc p_date
@starttime datetime,@endtime datetime
as
begin
SET LANGUAGE us_english
declare @i int
declare @ss int
set @i=0
while @i<datediff(dd,isnull(@endtime,getdate()),@starttime)
set @starttime=dateadd(dd,@i,@starttime)
if datename(weekday,@starttime)='Saturday' or datename(weekday,@starttime)='Sunday'
set @ss=@ss+24
set @i=@i+1

select datediff(Hour,isnull(y.endtime,getdate()),y.starttime) - @ss -
(select sum(case when datediff(Hour,j.endtime,j.starttime)>=4 then 24 else datediff(Hour,j.endtime,j.starttime) end )
from 假期表 j where j.uiserid=y.userid)
from 业务表 y
end
  • 打赏
  • 举报
回复

老大的,计算工作时间的
if exists (select * from dbo.sysobjects where id = object_id(N'[tb_worktime]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [tb_worktime]
GO

--定义工作时间表
CREATE TABLE tb_worktime(
ID int identity(1,1) PRIMARY KEY, --序号
time_start smalldatetime, --工作的开始时间
time_end smalldatetime, --工作的结束时间
worktime AS DATEDIFF(Minute,time_start,time_end) --工作时数(分钟)
)
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkTime]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_WorkTime]
GO

--计算两个日期之间的工作时间
CREATE FUNCTION f_WorkTime(
@date_begin datetime, --计算的开始时间
@date_end datetime --计算的结束时间
)RETURNS int
AS
BEGIN
DECLARE @worktime int
IF DATEDIFF(Day,@date_begin,@date_end)=0
SELECT @worktime=SUM(DATEDIFF(Minute,
CASE WHEN CONVERT(VARCHAR,@date_begin,108)>time_start
THEN CONVERT(VARCHAR,@date_begin,108)
ELSE time_start END,
CASE WHEN CONVERT(VARCHAR,@date_end,108)<time_end
THEN CONVERT(VARCHAR,@date_end,108)
ELSE time_end END))
FROM tb_worktime
WHERE time_end>CONVERT(VARCHAR,@date_begin,108)
AND time_start<CONVERT(VARCHAR,@date_end,108)
ELSE
SET @worktime
=(SELECT SUM(CASE
WHEN CONVERT(VARCHAR,@date_begin,108)>time_start
THEN DATEDIFF(Minute,CONVERT(VARCHAR,@date_begin,108),time_end)
ELSE worktime END)
FROM tb_worktime
WHERE time_end>CONVERT(VARCHAR,@date_begin,108))
+(SELECT SUM(CASE
WHEN CONVERT(VARCHAR,@date_end,108)<time_end
THEN DATEDIFF(Minute,time_start,CONVERT(VARCHAR,@date_end,108))
ELSE worktime END)
FROM tb_worktime
WHERE time_start<CONVERT(VARCHAR,@date_end,108))
+CASE
WHEN DATEDIFF(Day,@date_begin,@date_end)>1
THEN (DATEDIFF(Day,@date_begin,@date_end)-1)
*(SELECT SUM(worktime) FROM tb_worktime)
ELSE 0 END
RETURN(@worktime)
END
--小F-- 2010-03-24
  • 打赏
  • 举报
回复
记得精华帖子中有

石头也写过这个自定义假期的
ws_hgo 2010-03-24
  • 打赏
  • 举报
回复
好长啊

34,588

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧