繁体   English   中英

Oracle Query-分析功能的使用

[英]Oracle Query - Use of Analytical functions

假设我们已经将带有患者诊断数据的平面文件加载到名为“数据”的表中。 表结构为:

Create table Data (
Firstname varchar(50),
Lastname varchar(50),
Date_of_birth datetime,
Medical_record_number varchar(20),
Diagnosis_date datetime,
Diagnosis_code varchar(20))

平面文件中的数据如下所示:

'jane','jones','2/2/2001','MRN-11111','3/3/2009','diabetes'
'jane','jones','2/2/2001','MRN-11111','1/3/2009','asthma'
'jane','jones','5/5/1975','MRN-88888','2/17/2009','flu'
'tom','smith','4/12/2002','MRN-22222','3/3/2009','diabetes'
'tom','smith','4/12/2002','MRN-33333','1/3/2009','asthma'
'tom','smith','4/12/2002','MRN-33333','2/7/2009','asthma'
'jack','thomas','8/10/1991','MRN-44444','3/7/2009','asthma'

您可以假设没有两个患者具有相同的名字,姓氏和出生日期组合。 但是,一名患者可能在不同的日期进行几次探视。 这些都应具有相同的病历号。 问题是这样的:汤姆·史密斯有2个不同的病历号。 编写一个查询,该查询将始终显示所有像汤姆·史密斯(Tom Smith)一样的患者–病历号以上的患者。

我想出了以下查询。 它工作得很好,但是想知道是否有使用Oracle Analytical函数编写此查询的更好方法。 先感谢您

SELECT   a.firstname,
         a.lastname,
         a.date_of_birth,
         a.medical_record_number
FROM     data a, data b
WHERE        a.firstname = b.firstname
         AND a.lastname = b.lastname
         AND a.date_of_birth = b.date_of_birth
         AND a.medical_record_number <> .medical_record_number
GROUP BY a.firstname,
         a.lastname,
         a.date_of_birth,
         a.medical_record_number

可以通过解析函数来完成,但是它是否比在查询中进行联接更快*,取决于您拥有的数据。 您需要测试。

with data (firstname, lastname, date_of_birth, medical_record_number, diagnosis_date, diagnosis_code)
          as (select 'jane','jones','2/2/2001','MRN-11111',to_date('3/3/2009', 'mm/dd/yyyy'),'diabetes' from dual union all
              select 'jane','jones','2/2/2001','MRN-11111',to_date('1/3/2009', 'mm/dd/yyyy'),'asthma' from dual union all
              select 'jane','jones','5/5/1975','MRN-88888',to_date('2/17/2009', 'mm/dd/yyyy'),'flu' from dual union all
              select 'tom','smith','4/12/2002','MRN-22222',to_date('3/3/2009', 'mm/dd/yyyy'),'diabetes' from dual union all
              select 'tom','smith','4/12/2002','MRN-33333',to_date('1/3/2009', 'mm/dd/yyyy'),'asthma' from dual union all
              select 'tom','smith','4/12/2002','MRN-33333',to_date('2/7/2009', 'mm/dd/yyyy'),'asthma' from dual union all
              select 'jack','thomas','8/10/1991','MRN-44444',to_date('3/7/2009', 'mm/dd/yyyy'),'asthma' from dual),
-- end of mimicking your table and its data
      res as (select firstname,
                     lastname,
                     date_of_birth,
                     medical_record_number,
                     count(distinct medical_record_number) over (partition by firstname, lastname, date_of_birth) cnt_med_rec_nums
              from   data)
select distinct firstname,
                lastname,
                date_of_birth,
                medical_record_number
from   res
where  cnt_med_rec_nums > 1;

*顺便说一句,您的示例查询中的分组依据不是必需的; 将其切换为不同的记录会更有意义-因为您想要获取一组不同的记录,因此使您的意图更加清晰。

您可能可以使用HAVING子句而不是执行自HAVING稍微简化查询

SELECT   a.firstname,
         a.lastname,
         a.date_of_birth,
         MIN(a.medical_record_number) lowest_medical_record_number,
         MAX(a.medical_record_number) highest_medical_record_number
FROM     data a
GROUP BY a.firstname,
         a.lastname,
         a.date_of_birth
HAVING   COUNT( DISTINCT a.medical_record_number ) > 1

我在这里为每个患者返回最小和最大的病历号(如果大多数有此问题的患者只有两个而不是几十个,那我将这样做)。 如果愿意,您可以只返回一个,也可以返回所有病历编号的逗号分隔列表(如果大多数坏人都有数十个编号,这可能更有意义)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM