复杂的分组和时差

时间:2011-11-22 18:07:18

标签: sql tsql

所以我有一个日志表,其中包含如下数据:

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单元有两个不同的人分组,它将是:

Person 12394 10/28/2011 10:01至14:01 = 4小时出院

Person 12331 11/10/2011 from 9:08 to 11:08 = 2小时出院

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

正如其他人在评论中指出的那样,我认为我们所看到的设计/架构并不是很好。如果您可以保证行始终是顺序的,即对于每组两行,第一行是患者,其更改模式为“即将放电”,第二行是相同的患者,具有更改模式出院后,这应该有用。

;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