Как выбрать минимальное и максимальное время в течение 24 часов в T-SQL - PullRequest
0 голосов
/ 25 сентября 2019

Запись существует в следующем формате:

+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| StartDTM                    | EndDTM                      | PersonID | PersonName | Duration | TimeSheetItemID |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-17 17:48:00.0000000 | 2019-08-17 18:00:00.0000000 | 111111   | Smith, Bob | 0.200000 | 154446149       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-17 18:00:00.0000000 | 2019-08-17 23:00:00.0000000 | 111111   | Smith, Bob | 5.000000 | 154446149       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-17 23:00:00.0000000 | 2019-08-17 23:30:00.0000000 | 111111   | Smith, Bob | 0.500000 | 154446149       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-17 23:30:00.0000000 | 2019-08-18 00:00:00.0000000 | 111111   | Smith, Bob | 0.500000 | 154446149       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-18 00:00:00.0000000 | 2019-08-18 02:14:00.0000000 | 111111   | Smith, Bob | 2.233333 | 154446149       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-18 02:14:00.0000000 | 2019-08-18 06:18:00.0000000 | 111111   | Smith, Bob | 4.066666 | 154478804       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-25 17:48:00.0000000 | 2019-08-25 18:00:00.0000000 | 111111   | Smith, Bob | 0.200000 | 154745867       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-25 18:00:00.0000000 | 2019-08-25 23:00:00.0000000 | 111111   | Smith, Bob | 5.000000 | 154745867       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-25 23:00:00.0000000 | 2019-08-25 23:30:00.0000000 | 111111   | Smith, Bob | 0.500000 | 154745867       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-25 23:30:00.0000000 | 2019-08-26 00:00:00.0000000 | 111111   | Smith, Bob | 0.500000 | 154745867       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-26 00:00:00.0000000 | 2019-08-26 02:00:00.0000000 | 111111   | Smith, Bob | 2.000000 | 154745867       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+
| 2019-08-26 02:00:00.0000000 | 2019-08-26 05:54:00.0000000 | 111111   | Smith, Bob | 3.900000 | 154756492       |
+-----------------------------+-----------------------------+----------+------------+----------+-----------------+

Мне нужно выбрать MIN StartDTM и MAX EndDTM в течение 24 часов.Я попытался выбрать MIN (StartDTM) и MAX (EndDTM) в сочетании с GROUP BY PersonName и TimeSheetID, но это не удается, так как иногда в течение 24 часов существует более одного TimeSheetID (см. Строку 6 выше).

Мои желаемые результаты должны выглядеть следующим образом:

+-----------------------------+-----------------------------+----------+------------+-----------------+
| StartDTM                    | EndDTM                      | PersonID | PersonName | TimeSheetItemID |
+-----------------------------+-----------------------------+----------+------------+-----------------+
| 2019-08-17 17:48:00.0000000 | 2019-08-18 06:18:00.0000000 | 111111   | Smith, Bob | 154446149       |
+-----------------------------+-----------------------------+----------+------------+-----------------+
| 2019-08-25 17:48:00.0000000 | 2019-08-26 05:54:00.0000000 | 111111   | Smith, Bob | 154745867       |
+-----------------------------+-----------------------------+----------+------------+-----------------+

Этого можно достичь в T-SQL?

Ответы [ 3 ]

1 голос
/ 25 сентября 2019

Это проблема пробелов и островков.Вам нужно найти, где начинаются острова.В этом случае я рекомендую совокупный максимум.

select personId, min(startTM), max(endTM)
from (select t.*,
             sum(case when prev_maxEndTm >= dateadd(day, -1, startTm)
                      then 0  -- maximum is later than this record so no new island
                      else 1  -- maximum is earlier so new island
                  end) over (partition by personId order by startTm) as grp
      from (select t.*,
                   max(EndTm) over (partition by personId
                                    order by startTm
                                    rows between unbounded preceding and 1 preceding
                                   ) as prev_maxEndTm
            from t
           ) t
     ) t
group by personId;
0 голосов
/ 25 сентября 2019

Вы можете использовать опережение и отставание, как показано ниже, для решения этой проблемы:

;with cte_bucket as (
    select *, sum(difsec) over(partition by personid order by startdtm) bucket from (
        select *, coalesce(ABS(datediff(ss, startdtm, lag(enddtm) over( partition by personid order by startdtm))), 1) difsec
        from #table
    ) a 
)
select min(startdtm), max(enddtm), personid, personname, min(timesheetitemid)  from cte_bucket
group by personid, personname, bucket 

Код для справки:

https://rextester.com/UNF89433

+----+---------------------+---------------------+----------+------------+-----------------+
|    |      startDTM       |       endDTM        | personid | personname | TimesheetItemId |
+----+---------------------+---------------------+----------+------------+-----------------+
|  1 | 17.08.2019 17:48:00 | 18.08.2019 06:18:00 |   111111 | Smith, Bob |       154446149 |
|  2 | 25.08.2019 17:48:00 | 26.08.2019 05:54:00 |   111111 | Smith, Bob |       154745867 |
+----+---------------------+---------------------+----------+------------+-----------------+ 
0 голосов
/ 25 сентября 2019

Если я понимаю, что вы хотите мин / макс в день , то вам также нужно группировать по дням. непроверенный

select StartDTM, EndDTM, startTable.PersonID
   ,startTable.PersonName, startTable.TimeSheetItemID
from (
   select min(StartDTM) StartDTM, PersonID, PersonName, TimeSheetItemID
   from YourTable
   group by convert(date,StartDTM), PersonID, TimeSheetItemID, PersonName
) startTable
full outer join (
   select max(EndDTM) EndDTM, PersonID, TimeSheetItemID
   from YourTable
   group by convert(date,endDTM), PersonID, TimeSheetItemID
) EndTable
   on startTable.PersonID = endTable.PersonID
   and startTable.TimeSheetItemID = endTable.TimeSheetItemID
where convert(date,StartDTM) = convert(date,EndDTM)
order by startTable.PersonID,StartDTM

В расписаниях, которые не имеют как startDTM, так и endDTM в данный день, должны быть нулевые значения в этом запросе.

Если вас интересует любой 24-часовой период, тогда это совсем другое.

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