SQL Server 2008:计算多个表中多个日期范围中的键数

时间:2010-01-18 21:21:54

标签: sql sql-server sql-server-2008

感谢今天早上回答我问题的人们:

SQL Server 2008: Count Number of Keys In Multiple Date Ranges

这是它的扩展,我不清楚如何推广以前的解决方案。

我正在使用的数据库在几个表格中为一组患者提供药物,实验室值和诊断。与上述问题类似:

x = 1996至2008年:

我想计算在x年开具特定药物的患者数量,x年采用的特定实验室值(最后一个有点不同!) 1996年或之后首次给出的具体诊断,在第x年尚未解决。

编辑:事实证明,pt_id 是任何表中的主键 - 来自我一直在阅读的SELECT COUNT DISTINCT(pm.pt_id)(因为DISTINCT速度慢)但如果​​有效的解决方案使用不同,我会很好。

以下是仅2008年的查询,但我想再次查询将计算1996年至2008年每年的值。

SELECT COUNT (pm.pt_id)
FROM dm.medications pm
 /*patient was prescribed statins together with fibrates this year*/
WHERE pm.pt_id IN 
(
  SELECT statins.pt_id
  FROM dm.patient_medications statins 
  INNER JOIN dm.patient_medications other_meds
  ON statins.pt_id = other_meds.pt_id
  WHERE Year(other_meds.order_dts) = 2008
  AND Year(statins.order_dts) = 2008
  AND statins.generic_nm in ('Atorvastatin','Cerivastatin')
  AND other_meds.generic_nm in ('Clofibrate','Fenofibrate','Gemfibrozil')
)
/* patient had a diagnosis code in the list first diagnosed in 1996 or later and not yet resolved in this year */
WHERE pm.pt_id in
(
  SELECT pd.pt_id, 
  FROM dm.diagnoses pd
  WHERE pd.icd9_cd IN('728.89','729.1','710.4','728.3','729.0','728.81','781.0','791.3')
  AND Year(pd.init_noted_dts) >= 1996
  AND pd.rslvd_dts IS NOT NULL
  AND Year(pd.rslvd_dts) >= 2008
)
/* patient had a lab value above 1000 this year */ 
AND pm.pt_id IN
(
  SELECT pl.pt_id
  FROM dm.labs pl
  WHERE pl.lab_val > 1000
  AND pl.lab_val IS NOT NULL
  AND pl.lab_val < 999999
  AND pl.lab_nm = 'CK (CPK)'
  AND Year(pm.order_dts) = 2008
)
/* we have demographic information about this patient */
AND pm.pt_id IN
(
  SELECT p.pt_id
  FROM mrd.demographics p  
)
/* this is a real person */
AND pm.pt_id IS NOT NULL

1 个答案:

答案 0 :(得分:1)

试试这个:

SELECT COUNT(*), t1.year
FROM dm.medications pm
 /*patient was prescribed statins together with fibrates this year*/
inner join (
    SELECT statins.pt_id, Year(other_meds.order_dts) as Year
    FROM dm.patient_medications statins 
    INNER JOIN dm.patient_medications other_meds ON statins.pt_id = other_meds.pt_id
        AND Year(other_meds.order_dts) = Year(statins.order_dts)
    WHERE statins.generic_nm in ('Atorvastatin','Cerivastatin')
        AND other_meds.generic_nm in ('Clofibrate','Fenofibrate','Gemfibrozil')
) t1 on pm.pt_id = t1.pt_id
/* patient had a diagnosis code in the list first diagnosed in 1996 or later and not yet resolved in this year */
left outer join 
(
    SELECT pd.pt_id, Year(pd.rslvd_dts) as Year
    FROM dm.diagnoses pd
    WHERE pd.icd9_cd IN ('728.89','729.1','710.4','728.3','729.0','728.81','781.0','791.3')
        AND Year(pd.init_noted_dts) >= 1996
) t2 on pm.pt_id = t2.pt_id and t1.Year = t2.Year 
/* patient had a lab value above 1000 this year */ 
inner join (
SELECT pl.pt_id, Year(pm.order_dts) as Year
    FROM dm.labs pl
    WHERE pl.lab_val > 1000
        AND pl.lab_val < 999999
        AND pl.lab_nm = 'CK (CPK)'
) t3 on pm.pt_id = t3.pt_id and t2.Year = t3.Year
/* we have demographic information about this patient */
inner join (
    SELECT p.pt_id
    FROM mrd.demographics p    
) t4 on pm.pt_id = t4.pt_id and t3.Year = t4.Year
/* this is a real person */
where pm.pt_id IS NOT NULL
    and t1.year between 1996 and 2008
    and t2.Year is null
group by t1.year