Генерируйте процент на основе значений из другого столбца, используя PSQL - PullRequest
0 голосов
/ 05 апреля 2019

Я хотел бы создать новый столбец, который содержит значения 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 ]

1 голос
/ 05 апреля 2019

Использовать оконную функцию: 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;
0 голосов
/ 05 апреля 2019

Вы можете использовать оконную функцию с 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
0 голосов
/ 05 апреля 2019

Для этой цели у вас может быть два подзапроса, где один сгруппирован по 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
...