Oracle 多条记录根据某个字段获取相邻两条数据间的间隔天数,小于31天的记录都筛选出来

需求描述:在Oracle中 住院记录记录表为v_hospitalRecords,表中FIHDATE入院时间,FBIHID是住院号, 我想查询出每个患者在他们的所有住院记录中是否在一个月内再次入院(相邻的两条记录进行比较),并且住院记录大于一的患者在此入院的数据

1、方法一

1.1 如下图所示:假如住院号为155131的患者入院记录有三条,该病人第一次入院为2023-05-19 15:19:00、第二次为2023-06-13 15:19:00、第三次为2023-07-16 15:19:00,那么我们排序下计算相邻两个是否在31天内,并且显示这两条记录,sql如下:

SELECT FBIHID, FIHDATE,prev_fihdate,next_fihdate 
FROM (
  SELECT FBIHID, FIHDATE,
         LAG(FIHDATE) OVER (PARTITION BY FBIHID ORDER BY FIHDATE ASC) AS prev_fihdate,
         LEAD(FIHDATE) OVER (PARTITION BY FBIHID ORDER BY FIHDATE ASC) AS next_fihdate,
         COUNT(*) OVER (PARTITION BY FBIHID) AS admissions_count
  FROM v_jc_mae_zy
)
WHERE (FIHDATE - prev_fihdate <= 31 OR next_fihdate - FIHDATE <= 31)
AND admissions_count > 1;

我们解释下这段sql,这段sql是查找在 31 天内住院两次或以上的患者。查询从名为 v_jc_mae_zy 的视图中选择了四个列:FBIHIDFIHDATEprev_fihdatenext_fihdate。其中,FBIHID 表示患者的 ID,FIHDATE 表示患者住院的日期,prev_fihdate 表示患者上一次住院日期,next_fihdate 表示患者下一次住院日期。

为了计算 prev_fihdatenext_fihdate,该查询使用了 LAGLEAD 窗口函数。LAG 函数用于返回在当前行之前的行中指定列的值,而 LEAD 函数用于返回在当前行之后的行中指定列的值。这里根据 FBIHID 分组,按 FIHDATE 升序排序,以得到每个患者的住院日期的前一次和下一次住院日期。

接下来,该查询使用 COUNT 窗口函数计算了每个患者的住院次数,将其命名为 admissions_count

最后,该查询使用条件筛选语句 WHERE,选择了满足以下条件的行:

  • 当前住院日期与上一次住院日期之差小于等于 31 天,或者当前住院日期与下一次住院日期之差小于等于 31 天。
  • 患者的住院次数大于 1。

如图所示:

Oracle 多条记录根据某个字段获取相邻两条数据间的间隔天数,小于31天的记录都筛选出来_第1张图片
Oracle 多条记录根据某个字段获取相邻两条数据间的间隔天数,小于31天的记录都筛选出来_第2张图片

2、方法二

2.1我们如1.1所说一致,采用另外一种方法,sql如下:

SELECT fbihid,fihdate, 上一个入院日期, 一个月后日期
  FROM (SELECT v.*,
               LAG(FIHDATE) OVER(PARTITION BY FBIHID ORDER BY FIHDATE) AS 上一个入院日期,
               LAG(FIHDATE) OVER(PARTITION BY FBIHID ORDER BY FIHDATE) + INTERVAL '31' DAY AS 一个月后日期,
               COUNT(*) OVER(PARTITION BY FBIHID) AS 住院次数
          FROM v_jc_mae_zy v) a
 WHERE 住院次数 > 1
   AND (一个月后日期 > fihdate or (上一个入院日期 is null or 一个月后日期 is null));

我们解释下这段sql,这段sql用于查找在 31 天内住院两次或以上的患者。查询从名为 v_jc_mae_zy 的视图中选择了四个列:fbihidfihdate上一个入院日期一个月后日期。其中,fbihid 表示患者的 ID,fihdate 表示患者住院的日期,上一个入院日期 表示患者上一次住院日期,一个月后日期 表示患者上一次住院日期的一个月后的日期。

为了计算 上一个入院日期一个月后日期,该查询使用了 LAG 窗口函数和日期函数 INTERVALLAG 函数用于返回在当前行之前的行中指定列的值。这里根据 fbihid 分组,按 fihdate 升序排序,以得到每个患者的住院日期的前一次入院日期。INTERVAL '31' DAY 表示一个月的时间间隔。因此,LAG(FIHDATE) OVER(PARTITION BY FBIHID ORDER BY FIHDATE) + INTERVAL '31' DAY 表示上一次住院日期的一个月后的日期。

接下来,该查询使用 COUNT 窗口函数计算了每个患者的住院次数,将其命名为 住院次数

最后,该查询使用条件筛选语句 WHERE,选择了满足以下条件的行:

  • 患者的住院次数大于 1。
  • 上一次住院日期的一个月后的日期大于当前的住院日期,或者上一次住院日期或一个月后的日期为空。

总之,这个查询的目的是返回那些住院次数大于 1,且上一次住院日期的一个月后的日期大于当前的住院日期或者上一次住院日期或一个月后的日期为空的患者的 ID、住院日期、上一次住院日期和上一次住院日期的一个月后的日期。

方法有很多种,本次遇到了该问题,所以记录一下,如有错误,还请指正

你可能感兴趣的:(数据库,Oracle,oracle,数据库)