数码控科技猎奇Iphone动漫星座游戏电竞lolcosplay王者荣耀攻略allcnewsBLOGNEWSBLOGASKBLOGBLOGZSK全部技术问答问答技术问答it问答代码软件新闻开发博客电脑/网络手机/数码笔记本电脑互联网操作系统软件硬件编程开发360产品资源分享电脑知识文档中心IT全部全部分类全部分类技术牛文全部分类教程最新网页制作cms教程平面设计媒体动画操作系统网站运营网络安全服务器教程数据库工具网络安全软件教学vbscript正则表达式javascript批处理更多»编程更新教程更新游戏更新allitnewsJava新闻网络医疗信息化安全创业站长电商科技访谈域名会议专栏创业动态融资创投创业学院 / 产品经理创业公司人物访谈营销开发数据库服务器系统虚拟化云计算嵌入式移动开发作业作业1常见软件all电脑网络手机数码生活游戏体育运动明星影音休闲爱好文化艺术社会民生教育科学医疗健康金融管理情感社交地区其他电脑互联网软件硬件编程开发360相关产品手机平板其他电子产品摄影器材360硬件通讯智能设备购物时尚生活常识美容塑身服装服饰出行旅游交通汽车购房置业家居装修美食烹饪单机电脑游戏网页游戏电视游戏桌游棋牌游戏手机游戏小游戏掌机游戏客户端游戏集体游戏其他游戏体育赛事篮球足球其他运动球类运动赛车健身运动运动用品影视娱乐人物音乐动漫摄影摄像收藏宠物幽默搞笑起名花鸟鱼虫茶艺彩票星座占卜书画美术舞蹈小说图书器乐声乐小品相声戏剧戏曲手工艺品历史话题时事政治就业职场军事国防节日风俗法律法规宗教礼仪礼节自然灾害360维权社会人物升学入学人文社科外语资格考试公务员留学出国家庭教育学习方法语文物理生物工程学农业数学化学健康知识心理健康孕育早教内科外科妇产科儿科皮肤科五官科男科整形中医药品传染科其他疾病医院两性肿瘤科创业投资企业管理财务税务银行股票金融理财基金债券保险贸易商务文书国民经济爱情婚姻家庭烦恼北京上海重庆天津黑龙江吉林辽宁河北内蒙古山西陕西宁夏甘肃青海新疆西藏四川贵州云南河南湖北湖南山东江苏浙江安徽江西福建广东广西海南香港澳门台湾海外地区

求一个Sql日期算法求某时间段内自定义小时间段包含小时数-CSDN论坛

来源:互联网  责任编辑:小易  
本网有用户碰到这样的问题:求一个Sql日期算法求某时间段内自定义小时间段包含小时数-CSDN论坛,具体问题如下:

Sql日期算法求

本网根据需求用户需求,为用户寻得以下其他网友提供的解决方法,方法仅供参考,具体如下:

解决方案1:

e.g.

DECLARE @StartD DATETIME= '2017-01-02 02:02:21.287' ,
    @EndD DATETIME= '2017-01-05 08:00:21.287' ,
    @dd INT ,
    @hh INT ,
    @StartT DATETIME= '08:00' ,
    @EndT DATETIME= '20:00';


SELECT  @dd = DATEDIFF(dd, @StartD, @EndD) ,
        @hh = DATEPART(hh, @EndT) - DATEPART(hh, @StartT) ,
        @hh = @hh * ( @dd + 1 )
        + CASE WHEN @StartD > DATEADD(hh, DATEPART(hh, @StartT),
                                      CONVERT(VARCHAR(10), @StartD, 120))
               THEN DATEDIFF(hh, @StartD,
                             DATEADD(hh, @hh,
                                     CONVERT(VARCHAR(10), @StartD, 120)))
               ELSE 0
          END
        + CASE WHEN @EndD < DATEADD(hh, DATEPART(hh, @EndT),
                                    CONVERT(VARCHAR(10), @EndD, 120))
               THEN DATEDIFF(hh,
                             DATEADD(hh, DATEPART(hh, @EndT),
                                     CONVERT(VARCHAR(10), @EndD, 120)), @EndD)
               ELSE 0
          END;
SELECT  @hh;

/*
36
*/

解决方案2:

 好长的sql代码呀。啃啃

解决方案3:

谢谢。厉害了。不知道咋学sql能变这么精通

解决方案4:

set @StartD = '2017-01-02 07:02:21.287'
set @EndD = '2017-01-03 07:00:21.287'
算的结果是11小时,

set @StartD = '2017-01-02 08:02:21.287'
set @EndD = '2017-01-03 07:00:21.287'
算的结果是15小时,

理论上,7点比8点前,'2017-01-02 07:02:21.287' 至  '2017-01-03 07:00:21.287'
肯定会比 '2017-01-02 08:02:21.287' 至  '2017-01-03 07:00:21.287' 多

解决方案5:

set @StartD = '2017-01-02 08:00:00.00'
set @EndD   = '2017-01-03 08:00:00.00'
结果 12,对
set @StartD = '2017-01-02 08:00:00.00'
set @EndD   = '2017-01-03 09:00:00.00'
结果 13,对
set @StartD = '2017-01-02 09:00:00.00'
set @EndD   = '2017-01-03 09:00:00.00'
结果 16,错,应该是12

解决方案6:

这个函数有点问题。算不准确

解决方案7:

引用 6 楼 xiexue202 的回复:
这个函数有点问题。算不准确


比如?

只计算每天的8:00~20:00这个时间 段

比如:开始时间推迟 为9:00会减1小时,结束时间提前 为19:00会减1小时
都以小时数为单位,要精准需要按分钟计算,又会有新问题按小时是否把小时换算为小数

解决方案8:

如果按分钟计算是不是准确一点?

解决方案9:

改改,比如下方 结束时间为06:00不在08:00~20:00范围,01-05当天的小时数不计算 

e.g.

DECLARE @StartD DATETIME= '2017-01-02 02:02:21.287' ,
    @EndD DATETIME= '2017-01-05 06:00:21.287' ,
    @dd INT ,
    @hh INT ,
    @StartT DATETIME= '08:00' ,
    @EndT DATETIME= '20:00';


SELECT  @dd = DATEDIFF(dd, @StartD, @EndD) ,
        @hh = DATEPART(hh, @EndT) - DATEPART(hh, @StartT) ,
        @hh = @hh * ( @dd + 1 )
        + CASE WHEN @StartD > DATEADD(hh, DATEPART(hh, @StartT),
                                      CONVERT(VARCHAR(10), @StartD, 120))
               THEN DATEDIFF(hh, @StartD,
                             DATEADD(hh, @hh,
                                     CONVERT(VARCHAR(10), @StartD, 120)))
               ELSE 0
          END
        + CASE WHEN @EndD < DATEADD(hh, DATEPART(hh, @EndT),
                                    CONVERT(VARCHAR(10), @EndD, 120))
               THEN CASE WHEN @StartD > DATEADD(hh, DATEPART(hh, @EndT),
                                                CONVERT(VARCHAR(10), @EndD, 120))
                         THEN DATEDIFF(hh,
                                       DATEADD(hh, DATEPART(hh, @EndT),
                                               CONVERT(VARCHAR(10), @EndD, 120)),
                                       @EndD)
                         ELSE -@hh
                    END
               ELSE 0
          END;
SELECT  @hh;

/*
36
*/

解决方案10:

DECLARE @StartD DATETIME ,
    @EndD DATETIME ,
    @StartT DATETIME ,
    @EndT DATETIME ,
    @dd INT ,
    @hh INT 
 
set @StartD = '2017-01-02 9:00:00.00'
set @EndD   = '2017-01-03 19:00:00.00'

set @StartT = '8:00' 
set @EndT  = '20:00'

set @hh = 0
declare @NewStartT datetime,@NewEndT datetime,@dateS datetime,@dateE datetime
if @EndD <= @StartD
begin 
   set @hh = 0
end
else
begin
   set @dd= DATEDIFF(dd,@StartD,@EndD)
   while @dd>=0
   begin 
      set @NewStartT = substring(convert(varchar(23), @StartD, 121),1,11) + substring(convert(varchar(23), @StartT, 121),12,12)
      set @NewEndT = substring(convert(varchar(23), @StartD, 121),1,11) + substring(convert(varchar(23), @EndT, 121),12,12)      
      --判断开始日期大还是开始时间大
      if @StartD > @NewStartT set @dateS = @StartD
      else  set @dateS = @NewStartT

      if (@EndD > @NewEndT or @dd <> 0)set @dateE = @NewEndT
      else  set @dateE = @EndD
      
      select @dd as 天,@dateS as 开始,@dateE as 结束,DATEDIFF(hh,@dateS,@dateE)as 小时  --观察每天运算结果,可以去掉
      set @hh = @hh + DATEDIFF(n,@dateS,@dateE)  --精确到小时 DATEDIFF(hh,@dateS,@dateE),结果 select @hh

   set @dd=@dd-1
   set @StartD=dateadd(day,1,@NewStartT)
   end
end

select @hh/60.00

解决方案11:

解决方案12:

用9楼算法,当
set @StartD = '2017-01-02 9:00:00.00'
set @EndD   = '2017-01-03 19:00:00.00'

set @StartT = '8:00' 
set @EndT  = '20:00'
结果15小时,但应该是22小时才是。也不对

解决方案13:

引用 12 楼 baidu_35289351 的回复:
用9楼算法,当
set @StartD = '2017-01-02 9:00:00.00'
set @EndD   = '2017-01-03 19:00:00.00'

set @StartT = '8:00' 
set @EndT  = '20:00'
结果15小时,但应该是22小时才是。也不对


用以下测测,漏改一个位置@hh

DECLARE @StartD DATETIME= '2017-01-02 09:02:21.287' ,
    @EndD DATETIME= '2017-01-03 19:00:21.287' ,
    @dd INT ,
    @hh INT ,
    @StartT DATETIME= '08:00' ,
    @EndT DATETIME= '20:00';


SELECT  @dd = DATEDIFF(dd, @StartD, @EndD) ,
        @hh = DATEPART(hh, @EndT) - DATEPART(hh, @StartT),
        @hh = @hh * ( @dd + 1 )
        + CASE WHEN @StartD > DATEADD(hh, DATEPART(hh, @StartT),
                                      CONVERT(VARCHAR(10), @StartD, 120))
               THEN DATEDIFF(hh, @StartD,
                             DATEADD(hh, DATEPART(hh, @StartT),
                                     CONVERT(VARCHAR(10), @StartD, 120)))
               ELSE 0
          END
        + CASE WHEN @EndD < DATEADD(hh, DATEPART(hh, @EndT),
                                    CONVERT(VARCHAR(10), @EndD, 120))
               THEN CASE WHEN @StartD < DATEADD(hh, DATEPART(hh, @EndT),
                                                CONVERT(VARCHAR(10), @EndD, 120))
                         THEN DATEDIFF(hh,
                                       DATEADD(hh, DATEPART(hh, @EndT),
                                               CONVERT(VARCHAR(10), @EndD, 120)),
                                       @EndD)
                         ELSE -@hh
                    END
               ELSE 0
          END;
SELECT  @hh;

/*
22
*/

解决方案14:

13楼和我10楼的,也存在1个问题,就是负数

set @StartD = '2017-01-02 02:02:21.287'
set @EndD = '2017-01-05 06:00:21.287'

set @StartT = '8:00' 
set @EndT  = '20:00'
结果是 34,其实要36才是的,最后1天是-2.
我10楼,有个地方要改改
set @hh = @hh + DATEDIFF(n,@dateS,@dateE)
改为:
if DATEDIFF(n,@dateS,@dateE) >=0 set @hh = @hh + DATEDIFF(n,@dateS,@dateE)

--更正后

DECLARE @StartD DATETIME ,
    @EndD DATETIME ,
    @StartT DATETIME ,
    @EndT DATETIME ,
    @dd INT ,
    @hh INT 
 

set @StartD = '2017-01-02 02:02:21.287'
set @EndD = '2017-01-05 06:00:21.287'

set @StartT = '8:00' 
set @EndT  = '20:00'

set @hh = 0
declare @NewStartT datetime,@NewEndT datetime,@dateS datetime,@dateE datetime
if @EndD <= @StartD
begin 
   set @hh = 0
end
else
begin
   set @dd= DATEDIFF(dd,@StartD,@EndD)
   while @dd>=0
   begin 
      set @NewStartT = substring(convert(varchar(23), @StartD, 121),1,11) + substring(convert(varchar(23), @StartT, 121),12,12)
      set @NewEndT = substring(convert(varchar(23), @StartD, 121),1,11) + substring(convert(varchar(23), @EndT, 121),12,12)      
      --判断开始日期大还是开始时间大
      if @StartD > @NewStartT set @dateS = @StartD
      else  set @dateS = @NewStartT

      if (@EndD > @NewEndT or @dd <> 0)set @dateE = @NewEndT
      else  set @dateE = @EndD
      
      select @dd as 天,@dateS as 开始,@dateE as 结束,DATEDIFF(hh,@dateS,@dateE)as 小时  --观察每天运算结果,可以去掉
      if DATEDIFF(n,@dateS,@dateE)>=0 set @hh = @hh + DATEDIFF(n,@dateS,@dateE)  --精确到小时 DATEDIFF(hh,@dateS,@dateE),结果 select @hh

   set @dd=@dd-1
   set @StartD=dateadd(day,1,@NewStartT)
   end
end

select @hh/60.00

解决方案15:


  • 本文相关:
  • 站长必读,如何真正写好一篇原创文章
  • 互联网之路细嗅蔷薇 资深站长分享掘金之道
  • 企业站的站长的工作重心究竟有哪些
  • 浅析:行业门户网站的一些盈利模式
  • 3000IP的企业网站每天订单不到30个的苦恼
  • 网站想内外兼修?先学习提高网站可用性的6大原则
  • 浅谈网页设计中的简约之美
  • 网页改版实战:日本设计师如何彻底优化旅游网站?
  • 网页改版实战!日本设计师如何彻底优化招聘网站?
  • 2015年值得关注的21个网页设计趋势
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved