我有一张包含不同时间范围的表格:
Id Start Time End Time Points
1 0:00 3:00 10
2 3:01 6:00 20
3 6:01 23:59 30
现在我需要根据指定的时间计算两个日期范围之间达到的分数。
Start date = 11/9/2016 18:17:00 and
End date = 11/10/2016 01:20:00
我需要计算这两个日期之间获得的点数之和。 开始日期是18:17的时间属于Id 3,其点为30.因此计算将是,
18:17 to 23:59 -> 6 hrs -> 6 * 30 = 180 points
结束时间01:20属于Id 1
0:00 to 1:20 -> 2 hrs
(if minute is greater than zero, it is rounded to next hour, ie; 2) -> 2 * 10 = 20 points
所以获得的总分将是200分。 如果开始和结束日期的差异大于一天,那么考虑时差,对我没有帮助。
表格结构: Id - int, 开始时间 - 时间(7), 结束时间 - 时间(7), Points - int
如何使用SQL为此编写查询?
答案 0 :(得分:1)
这个问题很好。
您可以如下所示:
DECLARE @Tbl TABLE (Id INT, StartTime TIME, EndTime TIME, Points INT)
INSERT INTO @Tbl
VALUES
(1, '0:00', '3:00' , 10),
(2, '3:01', '6:00' , 20),
(3, '6:01', '23:59', 30)
DECLARE @StartDate DATETIME = '2016.11.09 18:17:00'
DECLARE @EndDate DATETIME = '2016.11.10 01:20:00'
;WITH CTE
AS
(
SELECT 1 AS RowId, @StartDate CurrentDate, 0 Point, @StartDate DateVal UNION ALL
SELECT
A.RowId ,
IIF((A.CurrentDate + A.EndTime) > @EndDate, @EndDate, DATEADD(MINUTE, 1, (A.CurrentDate + A.EndTime))) AS CurrentDate,
A.Points,
IIF((A.CurrentDate + A.EndTime) > @EndDate, @EndDate, (A.CurrentDate + A.EndTime)) DateVal
FROM
(
SELECT
C.RowId + 1 AS RowId,
CAST(CAST(CurrentDate AS DATE) AS DATETIME) CurrentDate,
CAST((SELECT T.EndTime FROM @Tbl T WHERE CAST(CurrentDate AS TIME) BETWEEN T.StartTime AND T.EndTime) AS DATETIME) AS EndTime,
(SELECT T.Points FROM @Tbl T WHERE CAST(CurrentDate AS TIME) BETWEEN T.StartTime AND T.EndTime) AS Points,
C.CurrentDate AS TempDate
FROM CTE C
) A
WHERE
A.TempDate <> IIF((A.CurrentDate + A.EndTime) > @EndDate, @EndDate, DATEADD(MINUTE, 1, (A.CurrentDate + A.EndTime)))
), CTE2
AS
(
SELECT
C.RowId ,
C.CurrentDate ,
C.Point ,
C.DateVal,
DATEDIFF(MINUTE, LAG(C.DateVal) OVER (ORDER BY C.RowId), C.DateVal) MinuteOfDateDiff
FROM
CTE C
)
SELECT
SUM(CEILING(C.MinuteOfDateDiff * 1.0 / 60.0) * C.Point)
FROM
CTE2 C
结果:200