【问题标题】:Generate percentage from based on values from other column using PSQL使用 PSQL 根据来自其他列的值生成百分比
【发布时间】:2019-08-27 01:59:32
【问题描述】:

我想根据表中其他列的值创建一个新列,其中包含 50%、60% 等值。从下面显示的输出中,我希望有基于“cnt”列中的值的“Desired Results”列。目前我的输入数据如下图所示

我只能从下面的查询中获取记录的数量。但是我无法生成百分比。你能帮帮我吗?

with test as
(
select subject_id,hadm_id,case 
             when valuenum between 80 and 110 then 1
             else 0
             end as "within_range"
         from labevents where itemid in ('50809','50931','51529') and 
hadm_id is not null 


) select subject_id,hadm_id,within_range,count(*) as cnt
from test group by subject_id,hadm_id,within_range

我希望输出如下所示

【问题讨论】:

  • 这些百分比背后的逻辑是什么
  • 如果你看上面的数据,对于 subject_id = 3,有两行,总 cnt 是 22,所以 14/22 是 64,8/22 是 36。其余的类似。对于只有一条记录的科目,则为 100 pc

标签: sql postgresql group-by percentage


【解决方案1】:

为此,您可以有两个子查询,其中一个按 hadm_id 分组,另一个不按 hadm_id 分组,并将它们都加入。

select a.* ,(a.cnt/b.cnt)*100 
from(select subject_id,hadm_id,within_range,count(*) as cnt
FROM (select subject_id,hadm_id,case 
             when valuenum between 80 and 110 then 1
             else 0
             end as "within_range"
         from labevents where itemid in ('50809','50931','51529') and 
hadm_id is not null) 
group by subject_id,hadm_id,within_range)a
INNER JOIN
(select subject_id,within_range,count(*) as cnt
FROM (select subject_id,hadm_id,case 
             when valuenum between 80 and 110 then 1
             else 0
             end as "within_range"
         from labevents where itemid in ('50809','50931','51529') and 
hadm_id is not null) 
group by subject_id,within_range)b
on a.subject_id,b.subject_id and a.within_range=b.within_range

【讨论】:

    【解决方案2】:

    使用窗口函数:http://www.postgresqltutorial.com/postgresql-window-function/

    with cte as
         (
           select subject_id,
                  hadm_id,
                  case
                    when valuenum between 80 and 110 then 1
                    else 0
                    end as "within_range"
             from labevents
            where itemid in ('50809', '50931', '51529')
              and hadm_id is not null
         ),
       subq as (
         select subject_id,
                hadm_id,
                within_range,
                count(*) as cnt
           from cte
          group by subject_id, hadm_id, within_range
       ) 
    select subq.*, (cnt / sum(cnt) OVER (PARTITION BY subject_id, hadm_id)) * 100 "Desired Results" 
    from subq;
    

    【讨论】:

    • 根据您的逻辑,您应该调整“PARTITION BY”列
    【解决方案3】:

    您可以将窗口函数与group by 一起使用。此外,CTE 并不是必需的,特别是因为 Postgres 允许为 group by 使用列别名:

    select subject_id, hadm_id,
           (case when valuenum between 80 and 110 then 1
                 else 0
            end) as within_range,
           count(*) as cnt,
           count(*) * 100.0 / sum(count(*)) over () as percentage
    from labevents
    where itemid in ('50809', '50931', '51529') and 
          hadm_id is not null 
    group by subject_id, hadm_id, within_range
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-30
      • 2019-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-17
      • 1970-01-01
      相关资源
      最近更新 更多