TSQL: перекрытие даты и времени и значения интервалов - PullRequest
1 голос
/ 02 февраля 2010

Нужна помощь в создании запроса для этого.

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) с суммой за каждый день, например:1006 *

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

Затем ищем общую сумму за весь запрошенный интервал.

Можете ли вы помочь построить этот запрос?

Ответы [ 2 ]

1 голос
/ 02 февраля 2010

Попробуйте это:

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 голосов
/ 02 февраля 2010

Проверить DATEDIFF в sqlserver. Я не уверен, какой сервер БД вы используете, но я думаю, что другие СУБД будут иметь что-то похожее или достаточно, чтобы вы могли создать свою собственную функцию для этого.

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

Похоже, я пропустил часть из нескольких дат этого. Чтобы разделить это на дни, я думаю, что вам почти придется обрабатывать каждую запись отдельно и сохранять во временной таблице или что-то в этом роде. Возможно, вы могли бы создать функцию, которая будет возвращать таблицу для каждой записи, которая разделяет длительности по дате, а затем это может быть СУММА для каждой даты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...