【问题标题】:Break a date range into hours per day for each job将日期范围分解为每个工作每天的小时数
【发布时间】:2026-01-18 12:45:01
【问题描述】:

昨天我要求一种有效的方法将日期范围分解为每天几小时,并在以下链接中收到了答案... Is there an efficient way to break a date range into hours per day?

现在我需要更进一步,为列表中的每个作业生成相同的内容。我有一张包含以下示例信息的表格...

+-------+-------------------------+-------------------------+
| JobID |        StartDate        |         EndDate         |
+-------+-------------------------+-------------------------+
|     1 | 2015-01-27 07:32:35.000 | 2015-01-28 14:39:35.000 |
|     2 | 2015-01-27 07:32:35.000 | 2015-01-29 16:39:35.000 |
|     3 | 2015-03-02 09:46:25.000 | 2015-03-05 17:24:15.000 |
+-------+-------------------------+-------------------------+

我需要得到一个类似下面的列表...

+-------+------------+-------+
| JobID |    Date    | Hours |
+-------+------------+-------+
|     1 | 2015-01-27 | 16.47 |
|     1 | 2015-01-28 | 14.65 |
|     2 | 2015-01-27 | 16.47 |
|     2 | 2015-01-28 | 24.00 |
|     2 | 2015-01-29 | 16.65 |
|     3 | 2015-03-02 | 14.23 |
|     3 | 2015-03-03 | 24.00 |
|     3 | 2015-03-04 | 24.00 |
|     3 | 2015-03-05 | 17.40 |
+-------+------------+-------+

能否修改递归 CTE(来自我包含的链接)以包含 JobID?

谢谢, 卡尔

【问题讨论】:

  • 您是否尝试过进行此修改?
  • 是的,但是我把它弄得太复杂了,一直在犯一堆逻辑错误。我在下面添加了我想出的内容。

标签: sql sql-server recursion common-table-expression


【解决方案1】:

这是我想出的解决方案...

DECLARE @testTable TABLE (JobID INT, startdate DATETIME, enddate DATETIME);
INSERT INTO @testTable VALUES (1,'2015-01-27 07:32:35.000','2015-01-28 14:39:35.000');
INSERT INTO @testTable VALUES (2,'2015-01-27 07:32:35.000','2015-01-29 16:39:35.000');
INSERT INTO @testTable VALUES (3,'2015-03-02 09:46:25.000','2015-03-02 17:24:15.000');

WITH cte AS ( 
SELECT JobID,CAST(startdate AS DATE) startdate,DATEDIFF(minute, startdate, DATEADD(DAY, 1, CAST(startdate AS DATE) ) ) / 60.0 hours,enddate from @testTable
UNION ALL 
SELECT JobID,DATEADD(DAY,1, startdate), DATEDIFF(minute, DATEADD(DAY,1, startdate), CASE WHEN DATEADD(DAY,2, startdate) > enddate
    THEN enddate ELSE DATEADD(DAY,2, startdate) END) / 60.0, enddate
FROM cte 
WHERE startdate <> CAST(enddate AS DATE) 
)

SELECT * FROM cte
ORDER BY JobID, startdate

【讨论】:

  • @ScottHunter 它对我有用。