使用PSQL根据其他列中的值生成百分比

时间:2019-04-05 07:56:26

标签: sql postgresql group-by percentage

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

enter image description here

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

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

我希望输出如下所示

enter image description here

3 个答案:

答案 0 :(得分:1)

使用窗口功能: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;

答案 1 :(得分:0)

为此,您可以具有两个子查询,其中一个子查询由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 :(得分:0)

您可以将窗口功能与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