【问题标题】:SQL: How to I create another "maximum" categorical value column based on multiple partitions?SQL:如何基于多个分区创建另一个“最大”分类值列?
【发布时间】:2022-01-26 17:23:14
【问题描述】:

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

Patient_ID department service_dte birth_dte count
12345 cardiac 1/2/21 6/18/78 5
12345 cardiac 8/20/21 6/18/78 5
12345 cardiac 10/28/21 6/18/78 5
12345 ortho 1/14/21 6/18/78 2
12345 ortho 7/7/21 6/18/78 2
12345 cardiac 8/20/21 6/18/78 5
12345 cardiac 4/19/21 6/18/78 5
12345 obgyn 4/1/21 6/18/78 1
78645 neuro 5/1/21 7/18/87 2
78645 neuro 7/7/21 7/18/87 2
78645 ent 7/7/21 7/18/87 1
32423 gastro 11/7/21 3/12/57 1

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

Patient_ID department service_dte birth_dte count max
12345 cardiac 1/2/21 6/18/78 5 cardiac
12345 cardiac 8/20/21 6/18/78 5 cardiac
12345 cardiac 10/28/21 6/18/78 5 cardiac
12345 ortho 1/14/21 6/18/78 2 cardiac
12345 ortho 7/7/21 6/18/78 2 cardiac
12345 cardiac 8/20/21 6/18/78 5 cardiac
12345 cardiac 4/19/21 6/18/78 5 cardiac
12345 obgyn 4/1/21 6/18/78 1 cardiac
78645 neuro 5/1/21 7/18/87 2 neuro
78645 neuro 7/7/21 7/18/87 2 neuro
78645 ent 7/7/21 7/18/87 1 neuro
32423 gastro 11/7/21 3/12/57 1 gastro

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

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

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

谢谢。

【问题讨论】:

  • 如果存在多个最大值怎么办,例如第二个ent 给患者78645

标签: mysql sql hadoop hive teradata


【解决方案1】:

在第二级聚合中也使用FIRST_VALUE() 窗口函数:

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

请参阅demo

【讨论】:

    【解决方案2】:

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

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

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

    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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-24
      • 2021-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      • 2015-03-10
      相关资源
      最近更新 更多