Сложная группировка и разница во времени - PullRequest
0 голосов
/ 22 ноября 2011

Итак, у меня есть таблица журнала, в которую заносятся данные вроде:

LogId   SiteNumber  Unit        IDNumber    LogCode     EnteredDateTime            ChangeMode           HowEntered
-----   ----------  ----        --------    -------     ----------------           ----------           -----------
851     1           16 - 0      23502       BDISCHSET   2011-11-12 11:48:08.890    Discharging Soon     SERIES
866     1           16 - 0      NULL        BDISCHRED   2011-11-12 21:45:11.657    Discharged           SERIES  
113     2           2001 - 0    12384       BDISCHSET   2011-10-28 09:27:08.773    Discharging Soon     SERIES
125     2           2001 - 0    NULL        BDISCHRED   2011-10-28 10:38:08.060    Discharged           SERIES
119     2           2002 - 0    12394       BDISCHSET   2011-10-28 10:01:12.443    Discharging Soon     SERIES
139     2           2002 - 0    NULL        BDISCHRED   2011-10-28 14:01:11.120    Discharged           SERIES
776     2           2002 - 0    12331       BDISCHSET   2011-11-10 09:08:09.443    Discharging Soon     SERIES
783     2           2002 - 0    NULL        BDISCHRED   2011-11-10 11:08:08.537    Discharged           SERIES

Что мне нужно сделать, это сгруппировать записи на человека и рассчитать количество времени, которое потребовалось для выписки.

Например: Блок 2002 - 0 состоит из двух разных людей, это будет:

Лицо 12394 28.10.2011 с 10:01 до 14:01 = 4 часа до выписки

Человек 12331 10.10.2011 с 9:08 до 11:08 = 2 часа до выписки

Любая помощь будет принята с благодарностью.

1 Ответ

1 голос
/ 22 ноября 2011

Как отмечают другие в комментариях, я не думаю, что дизайн / архитектура, на которую мы смотрим, великолепна. Если вы можете гарантировать, что строки ВСЕГДА будут последовательными, т. Е. Для каждого набора из двух строк, первая строка - это «Пациент с измененным режимом выписки в ближайшее время», а 2-я строка - это такой же пациент с режимом изменения Разряжается, тогда это должно работать.

;WITH OrderedTable AS
(
    SELECT  Unit
            , IDNumber
            , EnteredDateTime
            , ROW_Number() OVER (Partition BY Unit ORDER BY Unit) RN 
    FROM    @t -- YOUR TABLE NAME GOES HERE
)
SELECT  t1.Unit
        , t1.IDNumber
        , t1.EnteredDateTime as TimeIn
        , t2.EnteredDateTime as TimeOut
        , DATEDIFF(hour, t1.EnteredDateTime, t2.EnteredDateTime ) TimeElapsedInHours
FROM    OrderedTable t1
JOIN    OrderedTable t2 ON t1.Unit = t2.Unit AND t2.RN = t1.RN + 1
WHERE   t1.RN % 2 <> 0

Но я хочу пояснить - я не знаю, насколько безопасно это решение, основанное на ваших реальных данных. Однако он предоставит вам требуемые результаты на основе предоставленных вами образцов данных.

Даже если вы не можете использовать этот точный подход из-за вашей модели данных, я чувствую, что в нем есть несколько вещей, которые вы могли бы использовать для создания решения. Они сделают для интересного чтения, если ничего больше.

Вот тест, который я использовал ...

declare @t TABLE
(
    LogId   int,
    SiteNumber  int,
    Unit        varchar(50),
    IDNumber    int ,
    LogCode   varchar(50),
    EnteredDateTime  datetime,          
    ChangeMode    varchar(50),       
    HowEntered varchar(50)
)

insert into @t values (851, 1, '16 - 0', 23502, 'BDISCHSET', '2011-11-12 11:48:08.890', 'Discharging Soon', 'SERIES')
insert into @t values (866, 1, '16 - 0 ', NULL, 'BDISCHRED', '2011-11-12 21:45:11.657', 'Discharged', 'SERIES')
insert into @t values (113, 2, '2001 - 0', 12384, 'BDISCHSET', '2011-10-28 09:27:08.773', 'Discharging Soon', 'SERIES')
insert into @t values (125, 2, '2001 - 0', NULL, 'BDISCHRED', '2011-10-28 10:38:08.060', 'Discharged', 'SERIES')
insert into @t values (119, 2, '2002 - 0', 12394, 'BDISCHSET', '2011-10-28 10:01:12.443', 'Discharging Soon', 'SERIES')
insert into @t values (139, 2, '2002 - 0', NULL, 'BDISCHRED', '2011-10-28 14:01:11.120', 'Discharged', 'SERIES')
insert into @t values (776, 2, '2002 - 0', 12331, 'BDISCHSET', '2011-11-10 09:08:09.443', 'Discharging Soon', 'SERIES')
insert into @t values (783, 2, '2002 - 0', NULL, 'BDISCHRED', '2011-11-10 11:08:08.537', 'Discharged', 'SERIES')

;WITH OrderedTable AS
(
    SELECT  Unit
            , IDNumber
            , EnteredDateTime
            , ROW_Number() OVER (Partition BY Unit ORDER BY Unit) RN 
    FROM    @t -- YOUR TABLE NAME GOES HERE
)
SELECT  t1.Unit
        , t1.IDNumber
        , t1.EnteredDateTime as TimeIn
        , t2.EnteredDateTime as TimeOut
        , DATEDIFF(hour, t1.EnteredDateTime, t2.EnteredDateTime ) TimeElapsedInHours
FROM    OrderedTable t1
JOIN    OrderedTable t2 ON t1.Unit = t2.Unit AND t2.RN = t1.RN + 1
WHERE   t1.RN % 2 <> 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...