[英]The time that falls into a time period
I am looking for a way to calculate the time that falls into a datetime period.我正在寻找一种方法来计算属于日期时间段的时间。
I have a dataset that looks like this:我有一个看起来像这样的数据集:
+------+------------+-------------------------+-------------------------+
| Name | Date | Start | End |
+------+------------+-------------------------+-------------------------+
| Me | 06.02.2018 | 2018-02-06 22:26:00.000 | 2018-02-07 05:21:00.000 |
| Me | 08.02.2018 | 2018-02-08 19:00:00.000 | 2018-02-08 22:04:00.000 |
+------+------------+-------------------------+-------------------------+
I now want to check how much time falls into a certain time window, eg:我现在想检查多少时间落入某个时间窗口,例如:
So the result would look like this for the example above:因此,对于上面的示例,结果将如下所示:
+------+------------+-------------------------+-------------------------+----------+----------+----------+----------+
| Name | Date | Start | End | 6 - 20 | 20 - 23 | 23 - 6 | 0 - 4 |
+------+------------+-------------------------+-------------------------+----------+----------+----------+----------+
| Me | 06.02.2018 | 2018-02-06 22:26:00.000 | 2018-02-07 05:21:00.000 | 00:00:00 | 00:34:00 | 06:21:00 | 04:00:00 |
| Me | 08.02.2018 | 2018-02-08 19:00:00.000 | 2018-02-08 22:04:00.000 | 01:00 | 02:04 | 00:00:00 | 00:00:00 |
+------+------------+-------------------------+-------------------------+----------+----------+----------+----------+
I am struggling with a large line of code:我正在努力处理一大行代码:
CONVERT(varchar(5),IIF(a.end<(a.date+'00:00'),0,DATEADD(minute, DATEDIFF(MINUTE, IIF(a.start<(a.date+'00:00'),(a.date+'00:00'),a.start), IIF(a.end>(a.date+0+'04:00'),(a.date+0+'04:00'),a.end)), 0)), 114) [00-04],
This is exemplary for what I am trying to achieve but it doesn't work for this time period.这是我想要实现的目标的典范,但在这段时间内不起作用。 The +0
is there because in some cases I do have +1
and I am generating the lines of SQL in Excel at the moment. +0
在那里是因为在某些情况下我确实有+1
并且我现在正在 Excel 中生成 SQL 行。
Can anyone help me out here?有人可以帮我从这里出去吗?
What about the PIVOT?枢轴呢? Check it on rextester.com .在reextester.com上查看。
WITH
t AS (
SELECT 'Me' "Name",
CAST(a AS DATETIME) "Date",
CAST(b AS DATETIME) "Start",
CAST(c AS DATETIME) "End"
FROM (
VALUES ('20180206',
'20180206 22:26:00.000',
'20180207 05:21:00.000'),
('20180208',
'20180208 19:00:00.000',
'20180208 22:04:00.000')
) t(a, b, c)
),
d AS (
SELECT *
FROM (
VALUES (6, 20), (20, 23), (23, 30), (24, 28)
) t(beg, fin)
),
a AS (
SELECT t."Date", t."Start", t."End",
LTRIM(STR(d.beg)) + ' - ' + LTRIM(STR(d.fin)) Range,
DATEADD(hour, d.beg, t."Date") beg,
DATEADD(hour, d.fin, t."Date") fin
FROM t JOIN d
ON t."Start" <= DATEADD(hour, d.fin, t."Date") AND
t."End" >= DATEADD(hour, d.beg, t."Date")
),
b AS (
SELECT "Date", "Start", "End", Range,
LEFT(
CONVERT(CHAR(8),
DATEADD(minute,
DATEDIFF(minute,
IIF("Start" > beg, "Start", beg),
IIF("End" > fin, fin, "End")), 0), 8), 5) Duration
FROM a
)
SELECT "Date", "Start", "End",
COALESCE("6 - 20", '00:00') "6 - 20",
COALESCE("20 - 23", '00:00') "20 - 23",
COALESCE("23 - 30", '00:00') "23 - 6",
COALESCE("24 - 28", '00:00') "0 - 4"
FROM b
PIVOT (
MIN(Duration)
FOR Range
IN ("6 - 20", "20 - 23", "23 - 30", "24 - 28")
) AS p;
Here's one way.这是一种方法。 I got all dates from your table and formed needed time periods.我从您的表格中获取了所有日期并形成了所需的时间段。 Then looked for overlapping periods and calculated the time.然后寻找重叠的时间段并计算时间。 This query will not return rows which startDate
and endDate
on same day and before 6 o'clock此查询不会返回startDate
和endDate
在同一天和 6 点之前的行
declare @t table (
Date date
, StartDate datetime
, EndDate datetime
)
insert into @t
values
('20180206', '20180206 22:26:00.000', '20180207 05:21:00.000')
, ('20180207', '20180207 05:26:00.000', '20180207 22:21:00.000')
, ('20180207', '20180207 05:16:00.000', '20180207 05:21:00.000')
;with time_periods as (
select
distinct q.Date, t.n
, start_date = dateadd(hh, t.b, cast(q.Date as datetime))
, end_date = dateadd(hh, t.c, cast(q.Date as datetime))
from
@t q
cross apply (values (1, 6, 20), (2, 20, 23), (3, 23, 30), (4, 24, 28)) t(n, b, c)
)
select
Date, StartDate, EndDate
, [6 - 20] = right(concat('0', v1 / 3600), 2) + ':' + right(concat('0', v1 % 3600 / 60), 2) + ':' + right(concat('0', v1 % 60), 2)
, [20 - 23] = right(concat('0', v2 / 3600), 2) + ':' + right(concat('0', v2 % 3600 / 60), 2) + ':' + right(concat('0', v2 % 60), 2)
, [23 - 6] = right(concat('0', v3 / 3600), 2) + ':' + right(concat('0', v3 % 3600 / 60), 2) + ':' + right(concat('0', v3 % 60), 2)
, [0 - 4] = right(concat('0', v4 / 3600), 2) + ':' + right(concat('0', v4 % 3600 / 60), 2) + ':' + right(concat('0', v4 % 60), 2)
from (
select
Date, StartDate, EndDate
, v1 = max(iif(n = 1, diff, 0))
, v2 = max(iif(n = 2, diff, 0))
, v3 = max(iif(n = 3, diff, 0))
, v4 = max(iif(n = 4, diff, 0))
from (
select
m.Date, m.StartDate, m.EndDate, c.n
, diff = datediff(ss, iif(m.StartDate < c.start_date, c.start_date, m.StartDate), iif(m.EndDate < c.end_date, m.EndDate, c.end_date))
from
@t m
join time_periods c on m.StartDate <= c.end_date and m.EndDate >= c.start_date and c.Date = m.Date
) t
group by Date, StartDate, EndDate
) t
Output输出
Date StartDate EndDate [6 - 20] [20 - 23] [23 - 6] [0 - 4]
------------------------------------------------------------------------------------------------------------
2018-02-06 2018-02-06 22:26:00.000 2018-02-07 05:21:00.000 00:00:00 00:34:00 06:21:00 04:00:00
2018-02-07 2018-02-07 05:26:00.000 2018-02-07 22:21:00.000 14:00:00 02:21:00 00:00:00 00:00:00
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.