我想从5年(60)个月的住院数据中计算出每月的再入院率。在这段时间内,有些住院病人被再入院十次以上,而其他住院病人只有一次。
数据表如下所示。例如,ID为的住院病人。五年内只收过一次201,但身份证号为212次是4次,其中有2次在3天内被重新录取。
如何使用SQL中的此类数据计算医院每月30天的再入院率? 30天再入院是指患者在上次出院后30天内再次入院 谢谢!
->get()
答案 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
是重新入学的数量,rate
是readm/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。