如何使用SQL中的历史住院数据计算每月30天的再入院率?

时间:2019-05-11 13:07:51

标签: sql sql-server

我想从5年(60)个月的住院数据中计算出每月的再入院率。在这段时间内,有些住院病人被再入院十次以上,而其他住院病人只有一次。

数据表如下所示。例如,ID为的住院病人。五年内只收过一次201,但身份证号为212次是4次,其中有2次在3天内被重新录取。

如何使用SQL中的此类数据计算医院每月30天的再入院率? 30天再入院是指患者在上次出院后30天内再次入院 谢谢!

->get()

2 个答案:

答案 0 :(得分:1)

看起来,好像我有点迟了,但尽管如此-这是我的建议:

WITH mnths AS (
  select cast(1 as int) m 
  UNION ALL select m+1 FROM mnths WHERE m<60 
), admdis AS (
  SELECT *, 12*(year(admdate)-2014)+month(admdate)a, 12*(year(disdate)-2014)+month(disdate) d 
  FROM tbl t
  WHERE exists (SELECT 1 FROM tbl WHERE id=t.id AND disdate>DATEADD(day, -30, t.admdate) and sn<t.sn) 
)
SELECT (m-1)/12+2014 yr, 1+(m-1)%12 mn,m, count(id) readm 
FROM mnths LEFT JOIN admdis ON a=m
GROUP BY m 

我建立了一个数字表mnths,以生成一个月的常规网格,然后在该网格中对重新录取进行计数。 CTE admdis仅列出上次出院后不到30天的患者入院情况。

可在此处找到演示:https://rextester.com/TLM57882

修改

在查看forpas的解决方案时,我意识到我没有计算实际的再入院率 。这是一个完全符合此要求的修改版本:

WITH mnths AS (
  select cast(1 as int) m 
  UNION ALL select m+1 FROM mnths WHERE m<60 
), admdis AS (
  SELECT *, 12*(year(admdate)-2014)+month(admdate)a, 12*(year(disdate)-2014)+month(disdate) d,
        (SELECT 1 FROM tbl WHERE id=t.id AND disdate>DATEADD(day, -30, t.admdate) and sn<t.sn) readm
  FROM tbl t
)

SELECT (m-1)/12+2014 yr, 1+(m-1)%12 mn, count(id) totl ,count(readm) readm, 
       case when count(id)>0 THEN (0.+count(readm))/ count(id) ELSE 0 END rate
FROM mnths LEFT JOIN admdis ON a=m
GROUP BY m 

在计算费率时,我必须确保我没有“除以零”,因此,在那些没有录取的月份中,费率被假定为零(但并未实际计算)。

演示:https://rextester.com/NFCXQ24711

这是生成的结果:

yr    mn totl readm rate
2014    1   3   1   0.333333333333
2014    2   0   0   0.000000000000
2014    3   0   0   0.000000000000
2014    4   0   0   0.000000000000
2014    5   0   0   0.000000000000
2014    6   0   0   0.000000000000
2014    7   0   0   0.000000000000
2014    8   0   0   0.000000000000
2014    9   0   0   0.000000000000
2014    10  0   0   0.000000000000
2014    11  0   0   0.000000000000
2014    12  0   0   0.000000000000
2015    1   0   0   0.000000000000
2015    2   0   0   0.000000000000
2015    3   0   0   0.000000000000
2015    4   0   0   0.000000000000
2015    5   0   0   0.000000000000
2015    6   0   0   0.000000000000
2015    7   0   0   0.000000000000
2015    8   0   0   0.000000000000
2015    9   0   0   0.000000000000
2015    10  0   0   0.000000000000
2015    11  0   0   0.000000000000
2015    12  0   0   0.000000000000
2016    1   0   0   0.000000000000
2016    2   0   0   0.000000000000
2016    3   0   0   0.000000000000
2016    4   0   0   0.000000000000
2016    5   0   0   0.000000000000
2016    6   0   0   0.000000000000
2016    7   0   0   0.000000000000
2016    8   0   0   0.000000000000
2016    9   0   0   0.000000000000
2016    10  0   0   0.000000000000
2016    11  0   0   0.000000000000
2016    12  1   0   0.000000000000
2017    1   0   0   0.000000000000
2017    2   0   0   0.000000000000
2017    3   0   0   0.000000000000
2017    4   0   0   0.000000000000
2017    5   0   0   0.000000000000
2017    6   1   0   0.000000000000
2017    7   0   0   0.000000000000
2017    8   0   0   0.000000000000
2017    9   0   0   0.000000000000
2017    10  0   0   0.000000000000
2017    11  0   0   0.000000000000
2017    12  0   0   0.000000000000
2018    1   1   0   0.000000000000
2018    2   1   1   1.000000000000
2018    3   0   0   0.000000000000
2018    4   0   0   0.000000000000
2018    5   0   0   0.000000000000
2018    6   0   0   0.000000000000
2018    7   0   0   0.000000000000
2018    8   0   0   0.000000000000
2018    9   0   0   0.000000000000
2018    10  1   0   0.000000000000
2018    11  0   0   0.000000000000
2018    12  0   0   0.000000000000

totl列包含该时间段内的总入学人数,readm是重新入学的数量,ratereadm/totl的比率(如果是{ {1}}为0)。

答案 1 :(得分:0)

与此:

/**
 * 
 * @param {number} x A value to be doubled
 * @return {number} Twice x.
 *  
 */
function foo(x){
    return x*2 
}

const y = foo(2);

如果表的该行是重新提交,否则CTE返回with cte as ( select t.admdate, case when exists ( select 1 from tablename where id = t.id and sn <> t.sn and datediff(day, disdate, t.admdate) <= 30 ) then 1 else 0 end readmission from tablename t where datediff(month, t.admdate, getdate()) <= 60 ) select year(admdate) year, month(admdate) month, 100.0 * sum(readmission) / count(*) readmissionrate from cte group by year(admdate), month(admdate) order by year(admdate), month(admdate) 列,其值为readmission。否则返回1
然后,使用0,您将获得group by year(admdate), month(admdate)的重新提交总数,然后除以总行数。
参见demo