分解跨天的时间数据

数据库环境:SQL SERVER 2005

  在百度知道看到这道题目,原问题链接 MS SQL数据库关于时间循环如何处理跨天问题

  有如下表:
  -----------------------------------------------------------------------------------------------------------------
  设备 开始时间 结束时间 总时间(分钟)
  A 2015-08-01 17:06:49 2015-08-02 03:41:32 635
  B 2015-08-01 20:54:42 2015-08-03 23:59:59 3605
  ----------------------------------------------------------------------------------------------------------------
  需求:
  1、将每个设备的时间段循环得出每天总时间
  2、1天的时间计算结果必须是1440
  3、不能用游标方式处理
  需求结果集表如下:
  -----------------------------------------------------------------------------------------------------------------
  设备 开始时间 结束时间 总时间(分钟)
  A 2015-08-01 17:06:49 2015-08-01 23:59:59 413
  A 2015-08-02 00:00:00 2015-08-02 03:41:32 222
  B 2015-08-01 20:54:42 2015-08-01 23:59:59 185
  B 2015-08-02 00:00:00 2015-08-02 23:59:59 1440
  B 2015-08-03 00:00:00 2015-08-03 23:59:59 1440
  ----------------------------------------------------------------------------------------------------------------------

  

  该问题已有网友用递归实现,如果不用递归,我们该怎么处理呢?下面,我说一下我的实现思路:

  1.求出每个设备开始时间和结束时间相差的天数

  2.生成分解后的新时间

  3.求出分解后每个设备每天的时间差(分钟),如果是一整天,则计为1440;

  如果是最后一天,则用总时间减去前面的时间总和。

  SQL实现

/*测试数据*/
WITH    x0
          AS ( SELECT   ‘A‘ AS sb ,
                        CONVERT(DATETIME, ‘2015-08-01 17:06:49‘) AS date_begin ,
                        CONVERT(DATETIME, ‘2015-08-02 03:41:32‘) AS date_end ,
                        635 AS total_time
               UNION ALL
               SELECT   ‘B‘ AS sb ,
                        CONVERT(DATETIME, ‘2015-08-01 20:54:42‘) AS date_begin ,
                        CONVERT(DATETIME, ‘2015-08-03 23:50:52‘) AS date_end ,
                        3056 AS total_time
               UNION ALL
               SELECT   ‘C‘ AS sb ,
                        CONVERT(DATETIME, ‘2015-08-04 12:40:20‘) AS date_begin ,
                        CONVERT(DATETIME, ‘2015-08-05 23:59:59‘) AS date_end ,
                        2119 AS total_time
             ),/*计算两个时间点之间相差的天数*/
        x1
          AS ( SELECT   sb ,
                        date_begin ,
                        date_end ,
                        total_time ,
                        DATEDIFF(day, date_begin, date_end) AS cacl_day--开始时间和结束时间相差的天数
               FROM     x0
             ),/*将隔天的时间分解*/
        x2
          AS ( SELECT   sb ,
                        CASE WHEN msv.number = 0 THEN date_begin
                             ELSE CONVERT(VARCHAR(10), DATEADD(DAY, msv.number,
                                                              date_begin), 120)
                        END AS date_begin ,
                        CASE WHEN msv.number = x.cacl_day THEN date_end
                             ELSE CONVERT(VARCHAR(10), DATEADD(DAY, msv.number,
                                                              date_begin), 120)
                                  + ‘ 23:59:59‘
                        END AS date_end ,
                        total_time ,
                        CASE WHEN msv.number = x.cacl_day THEN 1
                             ELSE 0
                        END AS flag--如果是最后一天,标识为1,否则为0
               FROM     x1 x ,
                        master..spt_values msv
               WHERE    msv.type = ‘P‘
                        AND msv.number <= x.cacl_day
             ),
        x3
          AS ( SELECT   sb ,
                        date_begin ,
                        date_end ,
                        total_time ,
                        CASE WHEN CONVERT(CHAR(8), date_begin, 108) = ‘00:00:00‘
                                  AND CONVERT(CHAR(8), date_end, 108) = ‘23:59:59‘
                             THEN 1440
                             ELSE DATEDIFF(MINUTE, date_begin, date_end)
                        END AS cacl_time ,--如果是一整天,那么是1440分钟,否则,2个时间相减
                        flag ,
                        ROW_NUMBER() OVER ( PARTITION BY sb ORDER BY date_end ) AS rn--行号,用于后面统计各天的剩余分钟
               FROM     x2
             )
    SELECT  sb ,
            date_begin ,
            date_end ,
            CASE WHEN flag = 1 THEN total_time - ( SELECT   SUM(cacl_time)
                                                   FROM     x3 x
                                                   WHERE    x.sb = x3.sb
                                                            AND x.rn < x3.rn
                                                 )
                 ELSE cacl_time--最后一天的耗时是总时间减去前面的时间总和
            END AS cacl_time
    FROM    x3 

  我自己添加了一些测试数据,先看下原表的数据

  分解后的时间

  感兴趣的朋友,可以对比一下这2种方法实现的异同。

  

时间: 2024-08-02 10:59:28

分解跨天的时间数据的相关文章

浅析利用Hessian跨Web网站发送数据包

笔者,不玩游戏已经有一个月的时间了.昨天偶然发现大家都在玩吃鸡,于是好奇心作祟,昨个不知不觉就到了5点多.笔者现在的电脑配置是10年前的,现在最大的期待是能够有一台配置高.外观漂亮的电脑.好了,每天闲扯一下其实很开心,也主要是现在的游戏大都是3D体验感的,笔者晕3D渲染(配置低的电脑更明显),没办法啊.好了废话不多说了,现在我们实现一种跨Web网站的数据推送技术:从当前的Web网站生成一个数据文件包,然后将该数据文件包推送到另一个Web网站中,实现网站展现效果的实时推送.对此,笔者尝试使用Hes

AJAX跨域请求json数据的实现方法

这篇文章介绍了AJAX跨域请求json数据的实现方法,有需要的朋友可以参考一下 我们都知道,AJAX的一大限制是不允许跨域请求. 不过通过使用JSONP来实现.JSONP是一种通过脚本标记注入的方式,它是可以引用跨域URL的js脚本,不过需要提供一个回调函数(必须在您自己的页面上),因此,你可以自己处理结果. 让我们看看JSONP的是怎么在jQuery,MooTools的,Dojo Toolkit中实现的. jQuery的JSONPjQuery.getJSON方法:Js代码 jQuery.get

jquery跨域请求json数据

//服务端生成json数据json.php <?php $json=array("Volvo","BMW","SAAB"); $cb = $_GET['callback']; echo $cb.'('.json_encode($json, true).')'; ?> //客户端Ajax请求数据<script> $(document).ready(function() { var url="http://域名/js

Spring 跨重定向请求传递数据

在处理完POST请求后, 通常来讲一个最佳实践就是执行一下重定向.除了其他的一些因素外,这样做能够防止用户点击浏览器的刷新按钮或后退箭头时,客户端重新执行危险的POST请求. 在控制器方法返回的视图名称中,我们借助了" redirect:" 前缀的力量.当控制器方法返回的String 值 以" redirect:" 开头 的 话, 那么 这个 String 不是 用来 查找 视图 的, 而是 用来 指导 浏览器 进行 重定向 的 路径. 我们 可以 回头 看一下 程

mysql中获取一天、一周、一月时间数据的各种sql语句写法

今天抽时间整理了一篇mysql中与天.周.月有关的时间数据的sql语句的各种写法,部分是收集资料,全部手工整理,自己学习的同时,分享给大家,并首先默认创建一个表.插入2条数据,便于部分数据的测试,其中部分名词或函数进行了解释说明.直入主题! 创建表:create table if not exists t(   id int,   addTime datetime default ’0000-00-00 00:00:00′)添加两条初始数据:insert t values(1, ’2012-07

jQuery跨域请求,跨域Post提交数据的方法(.net/SQL技术交流群206656202 入群需注明博客园) - 思...

jQuery跨域请求,跨域Post提交数据的方法(.net/SQL技术交流群206656202 入群需注明博客园) - 思... 无聊透顶,网上看看技术文章吸收下精华,无意中发现很多开发人员在跨域请求方面很是疑惑,本人整理了一下曾经写过的代码供苦苦寻找解决方案的IT人一点灵感,如果认为自己是高手呢那么您就可以潇洒的飘过了~~废话不说了免得招人烦~~ 一.get方式实现跨域请求 这里我使用jQuery.getJSON()函数实现      a站点 http://bj.xxxx.com.aspx 请

IT忍者神龟之jQuery 使用 $.getJSON() 跨域获取 JSON 数据

假设在服务器上有文件 http://test.unmi.cc/json.php 文件,它的内容为: [代码 1] 01 02 03 04 05 06 07 08 09 10 <?php header('Content-type: application/json'); $user = array (     "name"  => "Unmi",     "blog" => "http://unmi.cc" )

跨域获取json数据

这是天气json的数据,这里是链接,json的数据接口  http://m.weather.com.cn/data/101010100.html json的数据格式 {"weatherinfo":{"city":"北京","city_en":"beijing","date_y":"2014年3月4 日","date":"",&q

本地主机作服务器解决AJAX跨域请求访问数据的方法

近几天学到ajax,想测试一下ajax样例,由于之前在阿里租用的服务器过期了,于是想着让本地主机既做服务器又做客户端,只是简单地测试,应该还行. 于是,下载了xampp,下载网址http://www.apachefriends.org ,只需要解压傻瓜式地安装就可以. 找到安装软件的目录,点击xampp-control.exe然后启动Apache服务, 打开浏览器,在地址栏输入localhost,出现如下图片,说明安装启动都没问题 现在编写两个简单的文本,一个txt文件,一个html代码: 截图