2010-02-02 64 views
1

需要帮助为此创建查询。TSQL:日期时间重叠和间隔值

Start    | End 
2009-01-01 06:00:00 | 2009-01-01 14:00:00 
2009-01-01 06:00:00 | 2009-01-02 06:00:00 
2009-01-02 07:00:00 | 2009-01-02 08:00:00 
2009-01-03 06:00:00 | 2009-01-03 14:00:00 
2009-01-03 09:00:00 | 2009-01-03 11:00:00 
2009-01-04 22:00:00 | 2009-01-05 06:00:00 
2009-01-05 01:00:00 | 2009-01-05 10:00:00 

我想获得非重叠的时间间隔(2009-01-01 00:00:00 - 2009-01-31 00:00:00) 与总和的每一天是这样的:

Date  | Duration 
2009-01-01 | 18 
2009-01-02 | 7 
2009-01-03 | 8 
2009-01-04 | 2 
2009-01-05 | 10 

然后寻找每整个申请时间间隔的总和。

你能帮助构建这个查询吗?

+0

请求的时间间隔是否始终在相应日期的午夜开始和停止? – 2010-02-02 19:03:08

+0

是的,这是主意。 – Solata 2010-02-02 21:27:19

+0

桌子的名字是什么? – 2010-02-02 21:59:35

回答

1

尝试这种情况:

WITH Times AS (
     SELECT DISTINCT(Start) AS Time FROM intervals 
     UNION ALL 
     SELECT DISTINCT([End]) AS Time FROM intervals), 
    Days AS (SELECT DISTINCT DATEADD(dd, 0, DATEDIFF(dd, 0, Time)) AS Time FROM Times), 
    Times2 AS (
     SELECT Time FROM times 
     UNION ALL 
     SELECT Time FROM days), 
    Times3 AS (SELECT ROW_NUMBER() OVER (ORDER BY Time) AS rn, Time FROM Times2), 
    Times4 AS (
     SELECT T1.Time AS Start, T2.Time AS [End] 
     FROM Times3 T1 
     JOIN Times3 T2 
     ON T1.rn + 1 = T2.rn), 
    IntervalParts AS (
     SELECT DISTINCT Times4.* 
     FROM Times4 
     JOIN intervals 
     ON Times4.Start >= intervals.Start AND Times4.[End] <= intervals.[End]), 
    IntervalsByDay AS (
     SELECT 
      DATEADD(dd, 0, DATEDIFF(dd, 0, Start)) AS Day, 
      DATEDIFF(hh, Start, [End]) AS Duration 
     FROM IntervalParts) 
SELECT Day, SUM(Duration) AS Duration 
FROM IntervalsByDay 
GROUP BY Day 

结果:

Day      Duration 
2009-01-01 00:00:00.000 18 
2009-01-02 00:00:00.000 7 
2009-01-03 00:00:00.000 8 
2009-01-04 00:00:00.000 2 
2009-01-05 00:00:00.000 10 

要将其限制在一定的范围,只需添加适当的WHERE子句。

+0

在查询中创建tmp表@interval并放@,但得到了“消息137,15级,状态2,行36 必须声明标量变量”@intervals“。 In line:“ON Times4.Start> = intervals.Start AND Times4。[End] <= intervals。[End]),” 任何想法是什么错误? – Solata 2010-02-02 21:52:40

+0

我不明白你为什么使用临时表。这似乎完全没有必要。你的数据不是真实的表格吗? – 2010-02-02 21:59:04

+0

温度只是为了测试。将尝试在真正的桌子上。临时表名是@interval。 – Solata 2010-02-02 22:04:20

0

在sqlserver中检出DATEDIFF。我不确定你使用的是哪个数据库服务器,但我想其他的RDBMS会有类似或足够的东西,以便可以创建自己的功能来执行此操作。

SELECT start, DATEDIFF(hh, start, end) FROM ...... 

看起来我错过了这个的多个日期部分。为了将这种情况分成几天,我认为你几乎必须分别处理每条记录并存储在临时表或其他东西中。也许你可以创建一个函数,为每个记录返回一个表格,按照日期分割持续时间,然后这可以是每个日期的SUMMED。