Как рассчитать ежемесячную 30-дневную реадмиссию по историческим стационарным данным в SQL? - PullRequest
0 голосов
/ 11 мая 2019

Я хочу рассчитать ежемесячную реадмиссию по стационарным данным за 5 лет (60) месяцев.Некоторые из стационарных пациентов были повторно госпитализированы более 10 раз за время, в то время как другие были только один раз.

Таблица данных выглядит следующим образом.В качестве примера, стационарный больной с ИД №.201 был принят только один раз в пять лет, но удостоверение личности нет.212 был 4 раза, и среди них два были реадмиссии в течение 3 дней.

Как я могу рассчитать ежемесячные 30-дневные показатели реадмиссии в больнице с такими данными в SQL?30-дневная реадмиссия - это когда госпитализируется в течение 30 дней после предыдущей выписки. Спасибо!

  ID   | SN    | Admdate     | Disdate       |
+------+-------+-------------+---------------+
|**212 | 1     | 2014-01-01  | 2014-01-12**  |
|201   | 2     | 2014-01-01  | 2014-01-10    |
|**212 | 598   | 2014-01-28  | 2014-02-12**  |
|**212 | 10000 | 2016-12-23  | 2016-12-29 ** |
| **212| 15112 | 2017-06-10  | 2017-06-21 ** |
|*401  | 20101 | 2018-01-01 | 2018-01-11     |*
|*401  | 21101 | 2018-02-01 | 2018-02-13     |*
|401   | 22101 | 2018-10-01  | 2018-10-11    |

Ответы [ 2 ]

1 голос
/ 11 мая 2019

Похоже, я немного опоздал, но тем не менее - вот мое предложение:

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 (или 0 в тех случаях, когда totl равно 0).

0 голосов
/ 11 мая 2019

При этом:

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)

CTE возвращает столбец readmission со значением 1, если эта строка таблицы является повторным доступом или 0.
Затем, используя group by year(admdate), month(admdate), вы получите общее количество разрешений на чтение с sum(readmission) и разделите на общее количество строк.
См. демо .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...