SQL Server ,按 24 小时时段拆分持续时间行

Posted

技术标签:

【中文标题】SQL Server ,按 24 小时时段拆分持续时间行【英文标题】:SQL Server , split a time duration row by 24 hour period 【发布时间】:2014-03-16 10:14:10 【问题描述】:

我正在使用 sql server 2008 r2。我正在尝试将一行按 FromDateTodate 之间的 24 小时时段范围划分。 例如,如果一个时间行给出如下,(FromDateTodate之间的范围是4天,所以我想要4行)

ID   FromDate                 Todate     
---- ------------------------ -------------------------
1    2014-04-01 08:00:00.000  2014-04-04 12:00:00.000

我想看到这样的结果:

ID   FromDate                 Todate                   DateDiff(HH)
---- ------------------------ -----------------------------------
1    2014-04-01 08:00:00.000  2014-04-01 23:59:59.000  15
1    2014-04-02 00:00:00.000  2014-04-02 23:59:59.000  23
1    2014-04-03 00:00:00.000  2014-04-03 23:59:59.000  23
1    2014-04-04 00:00:00.000  2014-04-04 12:00:00.000  12

【问题讨论】:

FromDate 2014-04-01 08:00:00.000 是真的还是你的意思是2014-04-01 00:00:00.000 FromDate 2014-04-01 08:00:00.000 - 上午 8 点开始 在本站搜索CTE日期,你会找到类似的。 【参考方案1】:

试试这个查询:

WITH TAB1 (ID,FROMDATE,TODATE1,TODATE) AS
(SELECT ID,
FROMDATE,
DATEADD(SECOND, 24*60*60 - 1, CAST(CAST(FROMDATE AS DATE) AS DATETIME)) TODATE1,
TODATE 
FROM TABLE1
UNION ALL
SELECT 
ID,
DATEADD(HOUR, 24, CAST(CAST(TODATE1 AS DATE) AS DATETIME)) FROMDATE,
DATEADD(SECOND, 2*24*60*60-1, CAST(CAST(TODATE1 AS DATE) AS DATETIME)) TODATE1,
TODATE
FROM TAB1 WHERE CAST(TODATE1 AS DATE) < CAST(TODATE AS DATE)
),
TAB2 AS
(SELECT ID,FROMDATE,
CASE WHEN TODATE1 > TODATE THEN TODATE ELSE TODATE1 END AS TODATE
FROM TAB1)
SELECT TAB2.*,
DATEPART(hh, TODATE) - DATEPART(hh, FROMDATE) [DateDiff(HH)] FROM TAB2;

SQL Fiddle

【讨论】:

效果很好,非常感谢,如何在单独的列中也显示 DATEDIFF(HH)?请帮助我。 欢迎你,我的朋友。我编辑了我的查询,它会根据需要显示DATEDIFF(HH)【参考方案2】:

http://sqlfiddle.com/#!6/36452/2

这应该是你需要的。 查询的第一部分是递归 CTE。这可用于创建日期数据。

WITH CTEDays AS
(
    SELECT CONVERT(date, '20140301') datevalue
 UNION ALL
    SELECT DATEADD(day, 1, C.datevalue)
    FROM CTEDays C
    WHERE DATEADD(day, 1, C.datevalue) <= '20140501'
)
SELECT 
    R.FromDate [FromOriginal]
    , R.ToDate [ToOriginal]
    , CDays.datevalue [RawDate]
    , WantedFrom = 
        CASE WHEN CONVERT(date, R.FromDate) = CDays.datevalue THEN R.FromDate
             ELSE CDays.datevalue
        END
    , WantedTo = 
        CASE WHEN CONVERT(date, R.ToDate) = CDays.datevalue THEN R.ToDate
             ELSE DATEADD(minute, 24*60-1, CONVERT(datetime, CDays.datevalue))
        END
FROM 
    tblRange R
    OUTER APPLY
    (
        SELECT C.datevalue
        FROM CTEDays C
        WHERE C.datevalue BETWEEN CONVERT(date, R.FromDate) AND CONVERT(date, R.ToDate)
    ) CDays

但是,如果 CTE 太慢或不方便,我建议为此设置一个日历表。

(正如我建议的here)

【讨论】:

【参考方案3】:

这应该可以满足您的需求。如果您在 from/to 范围内使用较大的日期范围,请记住设置 maxrecursion。

http://sqlfiddle.com/#!6/68b32/233

declare @tblTemp TABLE (id int identity, fromDate datetime, toDate datetime)

insert @tblTemp(fromDate, toDate)
select '2014-01-01 12:00:00', '2014-01-02 12:00:00'
union select '2014-04-01 12:00:00', '2014-04-02 12:00:00'


;with cte(i, f, t, e) as (
    select id as i, fromDate as f, DATEADD(SS, -1, DATEADD(HH, 1, fromDate)) as t, toDate as e
    from @tblTemp
    union all
    select cte.i as i, DATEADD(SS, 1, cte.t), DATEADD(HH, 1, cte.t) as t, cte.e as e
    from cte
    where DATEADD(HH,1,cte.t) <= cte.e
)
select i, f, t 
from cte
order by i,f

【讨论】:

以上是关于SQL Server ,按 24 小时时段拆分持续时间行的主要内容,如果未能解决你的问题,请参考以下文章

Oracle,将持续时间行拆分为一小时

工作高峰时段的 Sql Server 批量插入

R语言ggplot2可视化:可视化所有日期不同时段任务的持续时间将持续时间绘制成一条线(起始时间到结束时间),y轴表示活动发生的日期,x轴表示以小时为单位的时间

按 24 小时划分并使用 pyspark 或 panda 聚合

SQL Server - 如何根据将插入数据半小时的表中的几个参数来计算持续时间?

R语言ggplot2可视化:可视化所有日期不同时段任务的持续时间将持续时间绘制成一条线(起始时间到结束时间),y轴表示活动发生的日期,x轴表示以小时为单位的时间适应时间段跨越多天的情况