繁体   English   中英

SQL:如何基于多个分区创建另一个“最大”分类值列?

[英]SQL: How to I create another "maximum" categorical value column based on multiple partitions?

我有这张表(table_2),它基本上提供了患者信息和他们在特定日期访问的部门 -

患者 ID service_dte 出生日期 数数
12345 心脏 21 年 1 月 2 日 78 年 6 月 18 日 5
12345 心脏 21 年 8 月 20 日 78 年 6 月 18 日 5
12345 心脏 21 年 10 月 28 日 78 年 6 月 18 日 5
12345 21 年 1 月 14 日 78 年 6 月 18 日 2
12345 21 年 7 月 7 日 78 年 6 月 18 日 2
12345 心脏 21 年 8 月 20 日 78 年 6 月 18 日 5
12345 心脏 21 年 4 月 19 日 78 年 6 月 18 日 5
12345 妇产科 21 年 4 月 1 日 78 年 6 月 18 日 1
78645 神经 21 年 5 月 1 日 87 年 7 月 18 日 2
78645 神经 21 年 7 月 7 日 87 年 7 月 18 日 2
78645 耳鼻喉科 21 年 7 月 7 日 87 年 7 月 18 日 1
32423 21 年 11 月 7 日 57 年 3 月 12 日 1

我希望我想要的 output 生成一个附加列(最大),为每个“Patient_ID”提供最高重复“部门”,同时保持所有列不变,类似于下表 -

患者 ID service_dte 出生日期 数数 最大限度
12345 心脏 21 年 1 月 2 日 78 年 6 月 18 日 5 心脏
12345 心脏 21 年 8 月 20 日 78 年 6 月 18 日 5 心脏
12345 心脏 21 年 10 月 28 日 78 年 6 月 18 日 5 心脏
12345 21 年 1 月 14 日 78 年 6 月 18 日 2 心脏
12345 21 年 7 月 7 日 78 年 6 月 18 日 2 心脏
12345 心脏 21 年 8 月 20 日 78 年 6 月 18 日 5 心脏
12345 心脏 21 年 4 月 19 日 78 年 6 月 18 日 5 心脏
12345 妇产科 21 年 4 月 1 日 78 年 6 月 18 日 1 心脏
78645 神经 21 年 5 月 1 日 87 年 7 月 18 日 2 神经
78645 神经 21 年 7 月 7 日 87 年 7 月 18 日 2 神经
78645 耳鼻喉科 21 年 7 月 7 日 87 年 7 月 18 日 1 神经
32423 21 年 11 月 7 日 57 年 3 月 12 日 1

我试过下面的代码; 这为我提供了上表中患者就诊的科室数量——

select *
     , count(department) OVER (PARTITION BY patient_id, department) AS count
FROM table_1

但是,对于患者 12345 的最大列,它没有给我想要的值,它应该是心脏的。 我不是心脏,而是正畸。 请协助。 这是我正在尝试的代码 -

select *
   , max(department) OVER (PARTITION BY patient_id) AS max
FROM table_2

请帮助我以最佳方式获得最大列,并就我做错或可能做错的事情提出建议。

谢谢你。

在第二级聚合中也使用FIRST_VALUE() window function :

SELECT *, FIRST_VALUE(department) OVER (PARTITION BY patient_id ORDER BY count DESC) AS max
FROM (
  SELECT *, COUNT(*) OVER (PARTITION BY patient_id, department) AS count
  FROM table_1
) t

请参阅演示

count(department) OVER (PARTITION BY patient_id, department)将为结果中的每一行计算,只计算与该行相同的患者和部门的记录数(其中部门不是 null,具体而言)。 这不是你想要的。

max(department) OVER (PARTITION BY patient_id) AS max也将针对结果中的每一行计算,只需找到与该行相同的患者的部门名称的最大值。 这是该患者访问的所有科室按字母顺序排序的最后一个科室(这就是将 MAX() function 应用于字符值的方式),这不是您想要的。

我们想要一个子查询来返回每个患者访问次数最多的科室,下面是一个示例:

select 
      tbl1.*
    , MostVisited.department as MostVisitedDepartment
from 
    table_1 tbl1
    inner join
    (-- Take only the most visited department for each patient
        select *
        from (-- rank departments by number of times 
              -- visited for each patient; highest visited gets 1
              -- the result of a tie (the patient visited two+ departments the
              -- same number of times) depends on how the rdbms executes it.
            select 
                VisitCnt.*
              , row_number() over (partition by VisitCnt.patient_id
                                   order by VisitCnt.TimesVisited desc) as Seq
            from (-- Count each department visited by each patient
                select 
                    patient_id, department, count(*) as TimesVisited
                from table_1
                group by patient_id, department
                 ) VisitCnt
            ) VisitCntRnked
        where VisitCntRnked.Seq=1
    ) MostVisited
    on MostVisited.Patient_ID=tbl1.Patient_ID

至于“最佳”:这取决于您的意思:表大小、索引、表上的统计信息、您的特定数据库产品,以及,如果您想为整个(或大部分)运行此查询表的总体,或只有一小部分。 我们通常期望查询优化器在执行查询时考虑这些因素。 有很多例外,但优化查询需要比此问题中可用的信息更多的信息。

暂无
暂无

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

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