如何仅包含下一行在12小时内的行并相应地排名

时间:2017-02-09 10:08:20

标签: sql sql-server tsql sql-server-2012 rank

我们试图在SQL中只包含下一行在12小时内的行,基于时间戳。除此之外,我们还需要对行进行排名,以便确定初始联系,然后是时间范围内的联系人数。

不幸的是,我们不能在12小时内查找min()max(),因为日期范围可能更长(月),但联系之间的时间只能是12小时。一个人可能在整个日期范围内有多个联系人,初始联系人有一些特定于业务的要求(请参阅下面SQL中的InitialCall cte)。

到目前为止使用的SQL:

set nocount on;
set transaction isolation level read uncommitted;
set datefirst 1;
---------------------------------------------------------------------------------------
declare @FromDate as datetime = '2017-01-30T00:00:00';
declare @ToDate as datetime = '2017-02-05T23:59:59';
---------------------------------------------------------------------------------------
with [InitialCalls] as 
(
    select  
        d.PatientRef,
        d.CaseRef,
        d.PathwaysStartDate as [StartDate],
        d.PathwaysFinishDate as [FinishDate]
    from dbo.[111Data] as [d]
    where d.PathwaysStartDate between @FromDate and @ToDate
        and (d.MDSSpeaktoPrimaryCareService = 1 or d.MDSContactPrimaryCareService = 1) 
        and d.PathwaysDxCode in ('Dx05','Dx06','Dx07','Dx08','Dx11','Dx110','Dx1111','Dx116','Dx117','Dx12','Dx13','Dx14','Dx15','Dx17','Dx18','Dx19','Dx20','Dx21','Dx61','Dx80','Dx85','Dx86','Dx87','Dx93','Dx93')
        and d.PathwaysFinalTriage = 1
        and d.PathwaysAbandonedTriage = 0
        and d.ReferralCategory not in ('All Services Rejected','Unsuccessful Lookup','No DoS Selected')
),
[AllCalls] as 
(
    select distinct
        count(d.CaseRef) over (partition by d.PatientRef) as [CaseVol],
        d.PatientRef,
        d.CaseRef,
        d.PathwaysStartDate as [StartDate],
        d.PathwaysFinishDate as [FinishDate]
    from dbo.[111Data] as [d]
        inner join [InitialCalls] as [ic] on ic.PatientRef = d.PatientRef
    where d.PathwaysStartDate between ic.StartDate and dateadd(hour,12, ic.StartDate)
        and d.PathwaysFinalTriage = 1
        and d.PathwaysAbandonedTriage = 0
        and d.PatientRef = 'A3E14866-4DD5-4001-AF63-21819F49B401'
)
select 
    rank() over (partition by ac.PatientRef order by ac.StartDate) as [Rank],
    ac.PatientRef,
    ac.CaseRef,
    ac.StartDate,
    ac.FinishDate,
    lag(ac.FinishDate) over (partition by ac.PatientRef order by ac.FinishDate asc) as [PreviousRowFinishDate],
    datediff(hour, lag(ac.FinishDate) over (partition by ac.PatientRef order by ac.FinishDate asc), ac.StartDate) as [HoursDifference]
from [AllCalls] as [ac]
where ac.CaseVol > 1

当前输出: Current outputLink to current output

预期产量: Expected outputLink to expected output

在这种情况下,我们希望不包括第一行(因为这在12小时内没有跟进联系人),然后对重复联系人的每个实例进行排名。这样我们就可以跟踪有多少人使用特定问题进行调用,然后调用它来跟踪它。

编辑 - 表格创建和更改的SQL

declare @table as table
(
    [CaseRef] uniqueidentifier,
    [PatientRef] uniqueidentifier,
    [StartDate] datetime,
    [FinishDate] datetime
);

insert into @table
(
    [CaseRef],
    [PatientRef],
    [StartDate],
    [FinishDate]
)
values
('DB79C49E-938C-4C40-B48E-3389D9339759', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 00:22:41', '2017-01-30 00:28:06'),
('4BFA4E3B-D313-4777-A290-3C13601D5C95', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 22:00:46', '2017-01-30 22:10:24'),
('F910D4DE-3CEE-4429-8844-DDE860D08192', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 22:25:49', '2017-01-30 22:27:58'),
('DF28DC91-02E3-47F2-88E0-397C2CBCFE41', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 22:44:11', '2017-01-30 22:53:22'),
('D6964286-8AE7-46AB-8DA5-88A347015C4D', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 22:55:17', '2017-01-30 23:01:57'),
('660B2ED7-B715-4A6C-A92B-D80267C0E4F5', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 23:06:16', '2017-01-30 23:08:28'),
('903AC539-4BB1-44AB-AFDB-D86C13310011', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 23:15:21', '2017-01-30 23:16:02'),
('75B88E5F-4795-4A21-9EA6-3B41CE958250', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 23:28:31', '2017-01-30 23:29:53'),
('DD6A4BD5-EF75-44CE-9309-4C14B2A21FF4', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 23:45:42', '2017-01-30 23:46:13'),
('518319BA-0EDE-46D8-B0B7-E8CEB233DEDF', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 23:54:02', '2017-01-31 00:03:13'),
('FB5A5A54-E580-40F2-94FD-64E20EA5C4DD', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-31 16:13:01', '2017-01-31 16:21:02'),
('8A4FD0C3-59BF-43AB-A829-F2396D6FB26A', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-31 18:26:14', '2017-01-31 18:39:20'),
('8CB94AF1-9664-4081-A2E1-271ED16B147B', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-02-01 08:10:41', '2017-02-01 08:18:18'),
('0DC6B68B-0458-48DF-B286-C1A978653981', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-02-01 15:40:45', '2017-02-01 15:48:24'),
('DB239857-6870-4AD9-8149-69ED6151CCB2', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-02-02 16:54:40', '2017-02-02 17:10:27'),
('938CCFF4-66C9-48B1-BDB7-D9144D2BD522', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-02-02 19:29:18', '2017-02-02 19:30:14'),
('1EC730D0-AF85-45BF-BD06-12B23124151F', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-02-02 19:43:28', '2017-02-02 19:47:12');

set nocount on;
set transaction isolation level read uncommitted;
set datefirst 1;
with [InitialCalls] as 
(
    select  
        t.PatientRef,
        t.CaseRef,
        t.StartDate,
        t.FinishDate
    from @table as [t]
),
[AllCalls] as 
(
    select distinct
        count(t.CaseRef) over (partition by t.PatientRef) as [CaseVol],
        t.PatientRef,
        t.CaseRef,
        t.StartDate,
        t.FinishDate
    from @table as [t]
        inner join [InitialCalls] as [ic] on ic.PatientRef = t.PatientRef
    where t.StartDate between ic.StartDate and dateadd(hour,12, ic.StartDate)
)
select 
    rank() over (partition by ac.PatientRef order by ac.StartDate) as [Rank],
    ac.PatientRef,
    ac.CaseRef,
    ac.StartDate,
    ac.FinishDate,
    lag(ac.FinishDate) over (partition by ac.PatientRef order by ac.FinishDate asc) as [PreviousRowFinishDate],
    datediff(hour, lag(ac.FinishDate) over (partition by ac.PatientRef order by ac.FinishDate asc), ac.StartDate) as [HoursDifference]
from [AllCalls] as [ac]
where ac.CaseVol > 1;

最终编辑 - 在弗拉基米尔的帮助下提供答案

set nocount on;
set transaction isolation level read uncommitted;
set datefirst 1;
---------------------------------------------------------------------------------------
declare @FromDate as datetime = '2017-01-30T00:00:00';
declare @ToDate as datetime = '2017-02-05T23:59:59';
---------------------------------------------------------------------------------------

with [InitialCalls] as
(
    select  
        d.PatientRef,
        d.CaseRef,
        d.PathwaysStartDate,
        d.PathwaysFinishDate,
        d.PathwaysDxCode
    from dbo.[111Data] as [d]
    where d.PathwaysStartDate between @FromDate and @ToDate
        and (d.MDSSpeaktoPrimaryCareService = 1 or d.MDSContactPrimaryCareService = 1) 
        and d.PathwaysDxCode in ('Dx05','Dx06','Dx07','Dx08','Dx11','Dx110','Dx1111','Dx116','Dx117','Dx12','Dx13','Dx14','Dx15','Dx17','Dx18','Dx19','Dx20','Dx21','Dx61','Dx80','Dx85','Dx86','Dx87','Dx93','Dx93')
        and d.PathwaysFinalTriage = 1
        and d.PathwaysAbandonedTriage = 0
        and d.ReferralCategory not in ('All Services Rejected','Unsuccessful Lookup','No DoS Selected')
),
[AllCalls] as 
(
    select 
        d.PatientRef,
        d.CaseRef,
        d.CaseNumber,
        d.PathwaysStartDate,
        d.PathwaysFinishDate,
        isnull(lag(d.PathwaysStartDate) over (partition by d.PatientRef order by d.PathwaysStartDate), '1900-01-01') as [PreviousStartDate]
    from dbo.[111Data] as [d]
        inner join [InitialCalls] as [ic] on ic.PatientRef = d.PatientRef
    where d.PathwaysStartDate between ic.PathwaysStartDate and dateadd(hour,12, ic.PathwaysStartDate)
        and d.PathwaysFinalTriage = 1
        and d.PathwaysAbandonedTriage = 0
),
[InitialCallsMarkers] as
(
    select
        ic.PatientRef,
        ic.CaseRef,
        ic.CaseNumber,
        ic.PathwaysStartDate,
        ic.PathwaysFinishDate,
        iif(datediff(hour, ic.PreviousStartDate, ic.PathwaysStartDate) >= 12, 1, 0) as [Marker]
    from [AllCalls] as [ic]
),
[InitialCallsSequences] as
(
    select distinct
        icm.PatientRef,
        icm.CaseRef,
        icm.CaseNumber,
        icm.PathwaysStartDate,
        icm.PathwaysFinishDate,
        icm.Marker,
        sum(icm.Marker) over (partition by icm.PatientRef order by icm.PathwaysStartDate rows between unbounded preceding and current row) as [SequenceNumber]
    from [InitialCallsMarkers] as [icm]
),
[InitialCallsRanks] as
(
    select 
        ics.PatientRef,
        ics.CaseRef,
        ics.CaseNumber,
        ics.PathwaysStartDate,
        ics.PathwaysFinishDate,
        ics.SequenceNumber,
        ics.Marker,
        row_number() over (partition by ics.PatientRef, ics.SequenceNumber order by ics.PathwaysStartDate) as [Rank],
        count(*) over (partition by ics.PatientRef, ics.SequenceNumber) as [SequenceLength]
    from [InitialCallsSequences] as [ics]
)
select
    icr.[Rank],
    icr.PatientRef,
    icr.CaseRef,
    icr.CaseNumber,
    icr.PathwaysStartDate,
    icr.PathwaysFinishDate,
    icr.Marker,
    icr.SequenceNumber,
    icr.SequenceLength
from [InitialCallsRanks] as [icr]
where icr.SequenceLength > 1
order by icr.PatientRef, icr.PathwaysStartDate;

2 个答案:

答案 0 :(得分:2)

示例数据

declare @table as table
(
    [CaseRef] uniqueidentifier,
    [PatientRef] uniqueidentifier,
    [StartDate] datetime,
    [FinishDate] datetime
);

insert into @table
(
    [CaseRef],
    [PatientRef],
    [StartDate],
    [FinishDate]
)
values
('DB79C49E-938C-4C40-B48E-3389D9339759', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 00:22:41', '2017-01-30 00:28:06'),
('4BFA4E3B-D313-4777-A290-3C13601D5C95', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 22:00:46', '2017-01-30 22:10:24'),
('F910D4DE-3CEE-4429-8844-DDE860D08192', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 22:25:49', '2017-01-30 22:27:58'),
('DF28DC91-02E3-47F2-88E0-397C2CBCFE41', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 22:44:11', '2017-01-30 22:53:22'),
('D6964286-8AE7-46AB-8DA5-88A347015C4D', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 22:55:17', '2017-01-30 23:01:57'),
('660B2ED7-B715-4A6C-A92B-D80267C0E4F5', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 23:06:16', '2017-01-30 23:08:28'),
('903AC539-4BB1-44AB-AFDB-D86C13310011', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 23:15:21', '2017-01-30 23:16:02'),
('75B88E5F-4795-4A21-9EA6-3B41CE958250', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 23:28:31', '2017-01-30 23:29:53'),
('DD6A4BD5-EF75-44CE-9309-4C14B2A21FF4', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 23:45:42', '2017-01-30 23:46:13'),
('518319BA-0EDE-46D8-B0B7-E8CEB233DEDF', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-30 23:54:02', '2017-01-31 00:03:13'),
('FB5A5A54-E580-40F2-94FD-64E20EA5C4DD', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-31 16:13:01', '2017-01-31 16:21:02'),
('8A4FD0C3-59BF-43AB-A829-F2396D6FB26A', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-01-31 18:26:14', '2017-01-31 18:39:20'),
('8CB94AF1-9664-4081-A2E1-271ED16B147B', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-02-01 08:10:41', '2017-02-01 08:18:18'),
('0DC6B68B-0458-48DF-B286-C1A978653981', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-02-01 15:40:45', '2017-02-01 15:48:24'),
('DB239857-6870-4AD9-8149-69ED6151CCB2', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-02-02 16:54:40', '2017-02-02 17:10:27'),
('938CCFF4-66C9-48B1-BDB7-D9144D2BD522', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-02-02 19:29:18', '2017-02-02 19:30:14'),
('1EC730D0-AF85-45BF-BD06-12B23124151F', 'A3E14866-4DD5-4001-AF63-21819F49B401', '2017-02-02 19:43:28', '2017-02-02 19:47:12');

<强>查询

WITH
CTE_Prev
AS
(
    SELECT
        CaseRef
        ,PatientRef
        ,StartDate
        ,FinishDate
        ,ISNULL(LAG(StartDate) OVER (PARTITION BY PatientRef ORDER BY StartDate),
            '2000-01-01') AS PrevStart
    FROM @Table AS T
)
,CTE_Markers
AS
(
    SELECT
        CaseRef
        ,PatientRef
        ,StartDate
        ,FinishDate
        ,PrevStart
        ,CASE WHEN (DATEDIFF(hour, PrevStart, StartDate) >= 12) 
            THEN 1 ELSE 0 END AS GapIsLargeMarker
    FROM CTE_Prev
)
,CTE_Sequences
AS
(
    SELECT
        CaseRef
        ,PatientRef
        ,StartDate
        ,FinishDate
        ,PrevStart
        ,GapIsLargeMarker
        ,SUM(GapIsLargeMarker) OVER (PARTITION BY PatientRef ORDER BY StartDate 
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS SeqNumber
    FROM CTE_Markers
)
,CTE_Ranks
AS
(
    SELECT
        CaseRef
        ,PatientRef
        ,StartDate
        ,FinishDate
        ,PrevStart
        ,GapIsLargeMarker
        ,SeqNumber
        ,ROW_NUMBER() OVER (PARTITION BY PatientRef,SeqNumber ORDER BY StartDate) AS rnk
        ,COUNT(*) OVER (PARTITION BY PatientRef, SeqNumber) AS SeqLength
    FROM CTE_Sequences
)
SELECT
    CaseRef
    ,PatientRef
    ,StartDate
    ,FinishDate
    ,PrevStart
    ,GapIsLargeMarker
    ,SeqNumber
    ,rnk
    ,SeqLength
FROM CTE_Ranks
WHERE SeqLength > 1
ORDER BY PatientRef, StartDate;

<强>结果

+--------------------------------------+--------------------------------------+-------------------------+-------------------------+-------------------------+------------------+-----------+-----+-----------+
|               CaseRef                |              PatientRef              |        StartDate        |       FinishDate        |        PrevStart        | GapIsLargeMarker | SeqNumber | rnk | SeqLength |
+--------------------------------------+--------------------------------------+-------------------------+-------------------------+-------------------------+------------------+-----------+-----+-----------+
| 4BFA4E3B-D313-4777-A290-3C13601D5C95 | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-01-30 22:00:46.000 | 2017-01-30 22:10:24.000 | 2017-01-30 00:22:41.000 |                1 |         2 |   1 |         9 |
| F910D4DE-3CEE-4429-8844-DDE860D08192 | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-01-30 22:25:49.000 | 2017-01-30 22:27:58.000 | 2017-01-30 22:00:46.000 |                0 |         2 |   2 |         9 |
| DF28DC91-02E3-47F2-88E0-397C2CBCFE41 | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-01-30 22:44:11.000 | 2017-01-30 22:53:22.000 | 2017-01-30 22:25:49.000 |                0 |         2 |   3 |         9 |
| D6964286-8AE7-46AB-8DA5-88A347015C4D | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-01-30 22:55:17.000 | 2017-01-30 23:01:57.000 | 2017-01-30 22:44:11.000 |                0 |         2 |   4 |         9 |
| 660B2ED7-B715-4A6C-A92B-D80267C0E4F5 | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-01-30 23:06:16.000 | 2017-01-30 23:08:28.000 | 2017-01-30 22:55:17.000 |                0 |         2 |   5 |         9 |
| 903AC539-4BB1-44AB-AFDB-D86C13310011 | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-01-30 23:15:21.000 | 2017-01-30 23:16:02.000 | 2017-01-30 23:06:16.000 |                0 |         2 |   6 |         9 |
| 75B88E5F-4795-4A21-9EA6-3B41CE958250 | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-01-30 23:28:31.000 | 2017-01-30 23:29:53.000 | 2017-01-30 23:15:21.000 |                0 |         2 |   7 |         9 |
| DD6A4BD5-EF75-44CE-9309-4C14B2A21FF4 | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-01-30 23:45:42.000 | 2017-01-30 23:46:13.000 | 2017-01-30 23:28:31.000 |                0 |         2 |   8 |         9 |
| 518319BA-0EDE-46D8-B0B7-E8CEB233DEDF | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-01-30 23:54:02.000 | 2017-01-31 00:03:13.000 | 2017-01-30 23:45:42.000 |                0 |         2 |   9 |         9 |
| FB5A5A54-E580-40F2-94FD-64E20EA5C4DD | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-01-31 16:13:01.000 | 2017-01-31 16:21:02.000 | 2017-01-30 23:54:02.000 |                1 |         3 |   1 |         2 |
| 8A4FD0C3-59BF-43AB-A829-F2396D6FB26A | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-01-31 18:26:14.000 | 2017-01-31 18:39:20.000 | 2017-01-31 16:13:01.000 |                0 |         3 |   2 |         2 |
| 8CB94AF1-9664-4081-A2E1-271ED16B147B | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-02-01 08:10:41.000 | 2017-02-01 08:18:18.000 | 2017-01-31 18:26:14.000 |                1 |         4 |   1 |         2 |
| 0DC6B68B-0458-48DF-B286-C1A978653981 | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-02-01 15:40:45.000 | 2017-02-01 15:48:24.000 | 2017-02-01 08:10:41.000 |                0 |         4 |   2 |         2 |
| DB239857-6870-4AD9-8149-69ED6151CCB2 | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-02-02 16:54:40.000 | 2017-02-02 17:10:27.000 | 2017-02-01 15:40:45.000 |                1 |         5 |   1 |         3 |
| 938CCFF4-66C9-48B1-BDB7-D9144D2BD522 | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-02-02 19:29:18.000 | 2017-02-02 19:30:14.000 | 2017-02-02 16:54:40.000 |                0 |         5 |   2 |         3 |
| 1EC730D0-AF85-45BF-BD06-12B23124151F | A3E14866-4DD5-4001-AF63-21819F49B401 | 2017-02-02 19:43:28.000 | 2017-02-02 19:47:12.000 | 2017-02-02 19:29:18.000 |                0 |         5 |   3 |         3 |
+--------------------------------------+--------------------------------------+-------------------------+-------------------------+-------------------------+------------------+-----------+-----+-----------+

逐步运行查询,cte-by-cte并检查中间结果以了解其工作原理。

CTE_Prev从上一行返回PrevStart。如果它是患者的第一行,则为NULL,因此我将其设置为常量2001-01-01

如果两行之间的差距超过12小时,

CTE_Markers会将GapIsLargeMarker设置为1。它用1标记那些新的&#34;序列&#34;启动。

CTE_Sequences使用运行总计填充序列号SeqNumber

CTE_Ranks计算每个序列中的行号(rnk)以及每个序列中的行数(SeqLength)。

最后,我们只返回那些行数超过1行的序列。

答案 1 :(得分:0)

一般情况下你可以做

...WHERE EXISTS(
              SELECT 1 FROM dbo.[111Data] as [d2] 
                                  WHERE D2.StartDate BETWEEN 
                                        D1.StartDate 
                                        AND DATEADD(hour, 12, D1.StartDate)
                )

选择这样的记录,并在12小时内跟踪记录 - 你有没有尝试过类似的记录?

我不确定第二部分关于在时间范围内排名和计数的含义你可以使用子查询完成它

抱歉,我犯了一个错误,你需要从EXISTS

中仔细审查记录
...WHERE EXISTS(
          SELECT 1 FROM dbo.[111Data] as [d2] 
                              WHERE D2.StartDate >
                                    D1.StartDate 
                                    AND D2.StartDate <= DATEADD(hour, 12, D1.StartDate)
            )