简体   繁体   English

如何聚合到组级别,按时间顺序排序和枚举组? (在SQL服务器)

[英]How to aggregate to group level, order and enumerate groups chronologically? (in SQL Server)

Within a hospital encounter, a patient may be administered several different formulations of a medication, as shown here:在一次医院就诊中,患者可能会接受几种不同配方的药物治疗,如下所示:

Encounter遇到 Medication药物 Administration行政 Adm_Num Adm_Num
1 1个 A一种 8/31/21 11:33 AM 8/31/21 上午 11:33 1 1个
1 1个 B 8/31/21 6:25 PM 8/31/21 下午 6:25 2 2个
1 1个 C C 9/1/21 8:55 AM 9/1/21 上午 8:55 3 3个
1 1个 D 9/1/21 10:00 PM 9/1/21 晚上 10:00 4 4个
1 1个 B 9/2/21 11:27 AM 9/2/21 上午 11:27 5 5个
1 1个 B 9/2/21 10:00 PM 9/2/21 晚上 10:00 6 6个
1 1个 B 9/3/21 6:15 AM 9/3/21 早上 6:15 7 7
1 1个 B 9/3/21 3:30 PM 9/3/21 下午 3:30 8 8个
1 1个 D 9/3/21 8:30 PM 9/3/21 晚上 8:30 9 9

The task: For each encounter, I need to enumerate each formulation of the medication, like this:任务:对于每次遭遇,我需要列举药物的每种配方,如下所示:

Encounter遇到 Medication药物 Administration行政 Adm_Num Adm_Num Formulation公式
1 1个 A一种 8/31/21 11:33 AM 8/31/21 上午 11:33 1 1个 1 1个
1 1个 B 8/31/21 6:25 PM 8/31/21 下午 6:25 2 2个 2 2个
1 1个 C C 9/1/21 8:55 AM 9/1/21 上午 8:55 3 3个 3 3个
1 1个 D 9/1/21 10:00 PM 9/1/21 晚上 10:00 4 4个 4 4个
1 1个 B 9/2/21 11:27 AM 9/2/21 上午 11:27 5 5个 5 5个
1 1个 B 9/2/21 10:00 PM 9/2/21 晚上 10:00 6 6个 5 5个
1 1个 B 9/3/21 6:15 AM 9/3/21 早上 6:15 7 7 5 5个
1 1个 B 9/3/21 3:30 PM 9/3/21 下午 3:30 8 8个 5 5个
1 1个 D 9/3/21 8:30 PM 9/3/21 晚上 8:30 9 9 6 6个

I need to preserve the administration-level granularity in order to report on those data (and I'm in good shape there).我需要保留管理级别的粒度,以便报告这些数据(我在那里的状态很好)。

One strategy I tried was a CTE to find a medication-level value for each medication, such as the first administration instant, then apply that to the more granular administration-level data, like this:我尝试的一个策略是 CTE 来为每种药物找到药物级别值,例如第一次给药瞬间,然后将其应用于更精细的给药级别数据,如下所示:

WITH f as (
SELECT a.Encounter, a.Medication, MIN(Administration) as First_Adm,
 DENSE_RANK() OVER (PARTITION Encounter, Medication ORDER BY Administration) as Formulation
FROM a
GROUP BY a.Encounter, a.Medication
)
SELECT a.Encounter, a.Medication, a.Administration, a.Adm_Num, f.[First_Adm], f.Formulation
FROM a
INNER JOIN f ON (a.Encounter = f.Encounter AND a.Medication = f.Medication)
GROUP BY a.Encounter, a.Medication, a.Administration
ORDER BY a.Encounter, a.Medication, a.Administration

That worked well for the first few medications with single administrations, but it mishandled the reappearance of Medications B and D later in the encounter;这对于前几种单次给药的药物效果很好,但它对后来再次出现的药物 B 和 D 处理不当; it recognized Medication B from before, gave it the earlier MIN(Administration), and mislabeled it Formulation 2, as shown here:它从之前识别出药物 B,给它更早的 MIN(管理),并将其错误标记为配方 2,如下所示:

Encounter遇到 Medication药物 Administration行政 Adm_Num Adm_Num First_Adm First_Adm Formulation公式
1 1个 A一种 8/31/21 11:33 AM 8/31/21 上午 11:33 1 1个 8/31/21 11:33 AM 8/31/21 上午 11:33 1 1个
1 1个 B 8/31/21 6:25 PM 8/31/21 下午 6:25 2 2个 8/31/21 6:25 PM 8/31/21 下午 6:25 2 2个
1 1个 C C 9/1/21 8:55 AM 9/1/21 上午 8:55 3 3个 9/1/21 8:55 AM 9/1/21 上午 8:55 3 3个
1 1个 D 9/1/21 10:00 PM 9/1/21 晚上 10:00 4 4个 9/1/21 10:00 PM 9/1/21 晚上 10:00 4 4个
1 1个 B 9/2/21 11:27 AM 9/2/21 上午 11:27 5 5个 8/31/21 6:25 PM 8/31/21 下午 6:25 2 2个
1 1个 B 9/2/21 10:00 PM 9/2/21 晚上 10:00 6 6个 8/31/21 6:25 PM 8/31/21 下午 6:25 2 2个
1 1个 B 9/3/21 6:15 AM 9/3/21 早上 6:15 7 7 8/31/21 6:25 PM 8/31/21 下午 6:25 2 2个
1 1个 B 9/3/21 3:30 PM 9/3/21 下午 3:30 8 8个 8/31/21 6:25 PM 8/31/21 下午 6:25 2 2个
1 1个 D 9/3/21 8:30 PM 9/3/21 晚上 8:30 9 9 9/1/21 10:00 PM 9/1/21 晚上 10:00 4 4个

This is close, but not quite there.这很接近,但还不够。 The remaining challenge is to account for repeated formulations.剩下的挑战是解释重复的公式。

How can I group the administration-level data by medication formulation groups, order the formulations chronologically (making use of the time data), and assign a sequential value to each formulation, even if some are repeated?如何按药物配方组对管理级数据进行分组,按时间顺序排列配方(利用时间数据),并为每个配方分配一个顺序值,即使有些重复?

Thanks in advance for your help.在此先感谢您的帮助。

This is a type of "gaps and islands" problem.这是一种“差距和孤岛”问题。

One method is to first use lag or lead to check the adjacent row to identify where the data (Medication) changes, followed by summing these values for all preceding rows for each row in the results to generate the desired sequence:一种方法是首先使用lag 或 lead检查相邻行以确定数据(药物)更改的位置,然后对结果中每一行的所有前面行的这些值求和以生成所需的序列:

with c as (
    select *, 
      case when 
        Lag(medication) over (partition by encounter order by Administration) = medication 
      then 0 else 1 end Changed
    from t
)
select Encounter, Medication, Administration, Adm_Num,
  Sum(changed) over(partition by Encounter order by Administration) Formulation
from c;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM