2

我在 SO 中搜索但找不到直接答案。

有病人、医院、医疗科(急诊室、泌尿科、骨科、内科等)、医疗操作代码(检查、手术、核磁共振、超声等)和病人就诊日期。

患者去看医生,医生开药并要求再次进行控制检查。如果病人10 天后返回,他必须向同一家医院支付另一次检查费用。医院可能会在 10 天后指定一个日期,告知接下来的 10 天内没有空位,以获得检查费。

表结构如下:

Patient id.no   Hospital    Medical Branch     Medical Op. Code      Date
  1                 H1             M0                P1            01/05/2011
  5                 H1             M1                P9            03/05/2011
  3                 H2             M0                P2            09/05/2011
  1                 H1             M0                P1            14/05/2011 
  3                 H1             M0                P2            20/05/2011
  5                 H1             M2                P9            25/05/2011
  1                 H1             M0                P3            26/05/2011

在这里,探视病人没有。3号和5号不构成问题,因为病人没有。3 次访问不同的医院,5 号患者访问不同的医疗分支。即使他们在 10 天内访问,他们也会支付考试费用。

然而,1 号患者在 01/05 和 14/05 访问同一家医院、同一家分院并接受相同的流程(P1:检查)。

26/05 不算,因为它不是体检。

我要标记的是同一患者,同一医院,同一分支机构和同一医疗操作代码(即具体体检: P1 ),日期范围超过 10 天。

结果表的格式:

HOSPITAL        TOTAL NUM. of PATIENTS      NUM. of PATIENTS OUT OF DATE RANGE
  H1                        x                              a
  H2                        y                              b
  H3                        z                              c

谢谢。

4

3 回答 3

2

再一次,它是救援的分析功能。

此查询使用 LAG() 函数将 YOUR_TABLE 中的记录与表中的前一个(由 DATE 定义)匹配记录(由 PATIENT_ID 定义)链接。

select hospital_id
       , count(*) as total_num_of_patients      
       , sum (out_of_range) as num_of_patients_out_of_range
from (
    select patient_id
           , hospital_id
           , case
                   when hospital_id_1 = hospital_id_0
                   and  visit_1 > visit_0 + 10
                   and  med_op_code_1 = med_op_code_0
                   then 1
                   else 0
              end as out_of_range
    from (
            select patient_id
                   , hospital_id as hospital_id_1
                   , date as visit_1
                   , med_op_code as med_op_code_1
                   , lag (date) over (partition by patient_id order by date) as visit_0
                   , lag (hopital_id) over (partition by patient_id order by date) as hopital_id_0
                   , lag (med_op_code) over (partition by patient_id order by date) as med_op_code_0
            from your_table
            where med_op_code = 'P1'
        )
    )
group by hospital_id
/

警告:我没有测试过这段代码,所以它可能包含语法错误。下次我可以访问 Oracle 数据库时,我会检查它。

于 2011-08-24T21:13:18.657 回答
1

这有点粗糙,因为我手头没有 Oracle DB,但关键特性是相同的:分析函数 LAG()。连同它的配套函数 LEAD(),它们非常适合帮助处理诸如活动期间之类的事情。

这是我对代码的尝试:

select n.hospital, COUNT(n.patient_id) as patients_out_of_date_range
from (
    select *
    from (
        select d.*, lag(date, 1) over (partition by d.patient_id, d.hospital, d.medical_branch, d.medical_op_code order by d.date) as prev_date
        from datatable d inner join
            (
                select d.patient_id, d.hospital, d.medical_branch, d.medical_op_code
                from datatable d
                where d.medical_op_code = 'P1'
                group by d.patient_id, d.hospital, d.medical_branch, d.medical_op_code
                having COUNT(d.date) > 1
            ) t on d.patient_id  = t.patient_id and d.hospital = t.hospital and d.medical_branch = t.medical_branch and d.medical_op_code = t.medical_op_code
        ) m
    where date - prev_date > 10
    ) n
group by n.hospital

就像我说的,这没有经过测试,但它至少应该让你朝着正确的方向开始。

一些参考资料: http: //www.adp-gmbh.ch/ora/sql/analytical/lag.html

http://www.oracle-base.com/articles/misc/LagLeadAnalyticFunctions.php

于 2011-08-24T21:38:26.623 回答
1

我认为这就是你想要的:

WITH Patient_Visits (Patient_Id, Hospital_Id, Branch_Id, Visit_Date, Visit_Order) as ( 
                     SELECT Patient_Id, Hospital_Id, BranchId, Visit_Date, 
                            ROW_NUMBER() OVER(PARTITION BY Patient_ID, Hospital_Id, Branch_Id, 
                                              ORDER_BY Patient_Id, Hospital_Id, Branch_Id, Visit_Date)
                    FROM Hospital_Visits
                    WHERE Procedure_Id = 'P1'),
     Hospital_Recent_Visits (Hospital_Id, Recent_Visitor_Count) as (
                             SELECT a.Hospital_Id, COUNT(DISTINCT a.Patient_Id)
                             FROM Patient_Visits as a
                             JOIN Patient_Visits as b
                               ON b.Hospital_Id = a.Hospital_Id
                                  AND b.Branch_Id = a.Branch_Id
                                  AND b.Patient_Id = a.Patient_Id
                                  AND b.Visit_Order = a.Visit_Order - 1
                                  AND b.Visit_Date + 10 > a.Visit_Date
                             GROUP BY a.Hospital_Id, a.Patient_Id),
     Hospital_Patient_Count (Hospital_Id, Patient_Count) as (
                             SELECT Hospital_Id, COUNT(DISTINCT Patient_Id)
                             FROM Hospital_Visits
                             GROUP BY Hospital_Id, Patient_Id)
SELECT a.Hospital_Id, b.Patient_Count, c.Recent_Visitor_Count
FROM Hospitals as a
LEFT JOIN Hospital_Patient_Count as b
ON b.Hospital_Id = a.Hospital_Id
LEFT JOIN Hospital_Recent_Visits as c
ON c.Hospital_id = a.Hospital_Id

请注意,这是针对 DB2 系统编写和测试的。我认为 Oracle 数据库具有相关功能,因此查询仍应按书面方式工作。但是,DB2 似乎缺少 Oracle 拥有的一些 OLAP 功能(至少是我的版本),这可能有助于淘汰一些 CTE。

于 2011-08-24T21:42:29.583 回答