找到重叠的处方

时间:2013-05-28 16:27:27

标签: sql-server-2008 tsql

我有一堆患者处方,每个处方都有一定的开始日期和结束日期。我想找到患者在同一药物类别中服用超过一种药物超过2天的情况。持续时间应重叠。

表结构如下所示:

PatientID  StartDate  EndDate    Drug        DrugCategory
1          1/1/2013   1/5/2013   A           Cat1
1          1/1/2013   1/4/2013   B           Cat1
1          1/10/2013  1/12/2013  C           Cat1
2     .......    ........   .............  .........

如上所述,患者-1被处方3种相同类别的药物,前两种药物的持续时间超过2天。所以,对于这个例子,我希望查询返回Patient-1的前两个记录以及药物名称patientid。

希望有人可以提供帮助。这是使用SQL Server 2008 R2 btw。

3 个答案:

答案 0 :(得分:0)

您希望将它们作为单独的行还是作为一行?如果你想将它们作为单独的行,这应该工作;否则你可以转动结果。

create table want as
    select H.* from have H, have V
        where H.drug ne V.drug
            and H.PatientID=V.PatientID
            and H.startDate <= V.startDate
            and V.startDate <= H.endDate-2
    union select V.* from have H, have V
        where H.drug ne V.drug
            and H.PatientID=V.PatientID
            and H.startDate <= V.startDate
            and V.startDate <= H.endDate-2
            ;

我将H和V记录联合起来,我确信有一种更有效的方法可以做到这一点,但不能轻易拿出一个。 (Just H适用于给出的示例,但是对于更合适的示例,其中开始日期并不总是相等,您也需要V行。)

答案 1 :(得分:0)

请在使用前彻底测试。我已经对它进行了测试,到目前为止看起来还不错,但没有进行详尽的测试。如果您可以进一步测试它以满足您的要求,并且可以指出结果中的任何异常(如果存在)或将其转发并在需要时进行修改,那将会很棒。

--Test data:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Prescriptions](
    [PatientID] [int] NULL,
    [StartDate] [datetime] NULL,
    [EndDate] [datetime] NULL,
    [Drug] [varchar](50) NULL,
    [DrugCategory] [varchar](50) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT [dbo].[Prescriptions] ([PatientID], [StartDate], [EndDate], [Drug], [DrugCategory]) VALUES (1, CAST(0x0000A13A00000000 AS DateTime), CAST(0x0000A13E00000000 AS DateTime), N'D', N'Cat1')
INSERT [dbo].[Prescriptions] ([PatientID], [StartDate], [EndDate], [Drug], [DrugCategory]) VALUES (1, CAST(0x0000A13A00000000 AS DateTime), CAST(0x0000A13B00000000 AS DateTime), N'E', N'Cat1')
INSERT [dbo].[Prescriptions] ([PatientID], [StartDate], [EndDate], [Drug], [DrugCategory]) VALUES (1, CAST(0x0000A13800000000 AS DateTime), CAST(0x0000A13B00000000 AS DateTime), N'F', N'Cat1')
INSERT [dbo].[Prescriptions] ([PatientID], [StartDate], [EndDate], [Drug], [DrugCategory]) VALUES (1, CAST(0x0000A13800000000 AS DateTime), CAST(0x0000A13900000000 AS DateTime), N'G', N'Cat1')
INSERT [dbo].[Prescriptions] ([PatientID], [StartDate], [EndDate], [Drug], [DrugCategory]) VALUES (1, CAST(0x0000A12300000000 AS DateTime), CAST(0x0000A13900000000 AS DateTime), N'Z', N'Cat1')
INSERT [dbo].[Prescriptions] ([PatientID], [StartDate], [EndDate], [Drug], [DrugCategory]) VALUES (1, CAST(0x0000A12300000000 AS DateTime), CAST(0x0000A13A00000000 AS DateTime), N'Y', N'Cat1')
INSERT [dbo].[Prescriptions] ([PatientID], [StartDate], [EndDate], [Drug], [DrugCategory]) VALUES (1, CAST(0x0000A13900000000 AS DateTime), CAST(0x0000A13D00000000 AS DateTime), N'A', N'Cat1')
INSERT [dbo].[Prescriptions] ([PatientID], [StartDate], [EndDate], [Drug], [DrugCategory]) VALUES (1, CAST(0x0000A13900000000 AS DateTime), CAST(0x0000A13C00000000 AS DateTime), N'B', N'Cat1')
INSERT [dbo].[Prescriptions] ([PatientID], [StartDate], [EndDate], [Drug], [DrugCategory]) VALUES (1, CAST(0x0000A14200000000 AS DateTime), CAST(0x0000A14400000000 AS DateTime), N'C', N'Cat1')

使用的查询:

SELECT DISTINCT PatientID,StartDate,EndDate,Drug,DrugCategory FROM (
SELECT 
    DATEDIFF(dd,a.startdate,b.startdate) c1
    ,DATEDIFF(dd,a.enddate,b.enddate)c2
    ,DATEDIFF(dd,a.startdate,b.enddate) c3
    ,DATEDIFF(dd,a.enddate,b.startdate) c4
    ,DATEDIFF(dd,a.startdate,b.enddate)+DATEDIFF(dd,a.enddate,b.startdate) c34
    ,a.PatientID
    ,a.StartDate
    ,a.EndDate
    ,a.Drug 
    ,a.DrugCategory 
    ,b.PatientID  AS PatientID1
    ,b.StartDate  AS StartDate1
    ,b.EndDate   AS EndDate1
    ,b.Drug   AS Drug1
    ,b.DrugCategory  DrugCategory1
FROM Prescriptions a
,Prescriptions b
WHERE a.patientid=b.patientid
AND a.DrugCategory= b.DrugCategory
and a.drug<>b.drug
)a 
WHERE c1*c2*c3*c4 <0
AND c3>2
and c4<=-2
ORDER BY 1,2,3,4

结果:

PatientID   StartDate               EndDate                 Drug                                               DrugCategory
----------- ----------------------- ----------------------- -------------------------------------------------- --------------------------------------------------
1           2012-12-10 00:00:00.000 2013-01-02 00:00:00.000 Y                                                  Cat1
1           2012-12-31 00:00:00.000 2013-01-03 00:00:00.000 F                                                  Cat1
1           2013-01-01 00:00:00.000 2013-01-04 00:00:00.000 B                                                  Cat1
1           2013-01-01 00:00:00.000 2013-01-05 00:00:00.000 A                                                  Cat1
1           2013-01-02 00:00:00.000 2013-01-06 00:00:00.000 D                                                  Cat1

(5 row(s) affected)

答案 2 :(得分:0)

您应该能够做的是将药物表与自己的药物名称不同,并且第二个实例的startDate OR endDate跨越第一个的startDate / endDate。然后,通过减去max(startDates)和min(endDates)之间的天数来确定重叠范围。如果重叠超过2天,则返回行:

select *, datediff(d, start_max, end_min) as overlap
from (
    SELECT 
      P.PatientID, P.StartDate, P.EndDate, P.Drug, P.DrugCategory, 
      P1.StartDate AS p1_start, P1.EndDate AS p1_end, P1.Drug AS p1_drug, 
      CASE WHEN p.startdate >= P1.startdate THEN p.startdate ELSE P1.startdate END AS start_max, 
      CASE WHEN p.EndDate <= P1.EndDate THEN p.EndDate ELSE P1.EndDate END AS end_min
    FROM  
      dbo.Prescriptions p INNER JOIN
      dbo.Prescriptions AS P1 ON 
      P.PatientID = P1.PatientID AND 
      P.DrugCategory = P1.DrugCategory AND 
      P.Drug <> P1.Drug
    WHERE 
      (P1.StartDate >= P.StartDate AND P1.StartDate <= P.EndDate) OR
      (P1.EndDate >= P.StartDate AND P1.EndDate <= P.EndDate)
) t
where
datediff(d, start_max, end_min) > 2