简体   繁体   English

属于时间段的时间

[英]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:我现在想检查多少时间落入某个时间窗口,例如:

  • 0600 to 2000 0600 至 2000
  • 2000 to 2300 2000 至 2300
  • 2300 to 0600 (next day) 2300 至 0600(次日)
  • 0000 to 0400 (next day) 0000 到 0400(第二天)

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此查询不会返回startDateendDate在同一天和 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM