Обновить столбец таблицы на основе многострочной операции сравнения в Postgres - PullRequest
0 голосов
/ 06 марта 2020

У меня есть следующая таблица в postgres

id          num
EBI-1002144 1
EBI-1002144 1
EBI-1002142 2
EBI-1002142 2
EBI-1002635 1
EBI-1002635 1
EBI-1002635 2
EBI-1002635 2
EBI-1003351 1
EBI-1003351 1
EBI-1003351 2
EBI-1003351 2
EBI-1003469 1
EBI-1003469 1
EBI-1003469 2
EBI-1003469 2
EBI-1003574 1
EBI-1003574 1
EBI-1003574 2
EBI-1003574 2

Я хочу добавить еще один столбец к этой таблице на следующих условиях:

--> group by id 
--> calculate max of num
--> if the value of num > 1 per id, then assign the id as label 'A' else 'B'

Я могу выяснить максимальное значение, но не может понять, как назначить значение каждой строке с общим идентификатором.

Ожидаемый результат:

id          num  label
EBI-1002144 1    B
EBI-1002144 1    B
EBI-1002142 1    A
EBI-1002142 2    A
EBI-1002635 1    A
EBI-1002635 1    A
EBI-1002635 2    A
EBI-1002635 2    A
EBI-1003351 1    A
EBI-1003351 1    A
EBI-1003351 2    A
EBI-1003351 2    A
EBI-1003469 1    A
EBI-1003469 1    A
EBI-1003469 2    A
EBI-1003469 2    A
EBI-1003574 1    A
EBI-1003574 1    A
EBI-1003574 2    A
EBI-1003574 2    A

Ответы [ 2 ]

1 голос
/ 06 марта 2020

Используйте функции окна:

select t.*,
       (case when max(num) over (partition by id) > 1 then 'A' else 'B' end) as label
from t;

Если вы действительно хотите обновить таблицу, агрегируйте и join:

update t
    set label = (case when max_num > 1 then 'A' else 'B' end)
    from (select id, max(num) as max_num
          from t 
          group by id
         ) tt
    where tt.id = t.id
0 голосов
/ 06 марта 2020

Вы можете использовать оконные функции.

Если вы хотите оператор update:

with cte as (
    select 
        id,
        case 
            when max(num) over(partition by id) > 1 
            then 'A' 
            else 'B' 
        end label
    from mytable t
)
update mytable 
set label = cte.label
from cte 
where cte.id = mytable.id

Если вы хотите select:

select 
    t.*,
    case 
        when max(num) over(partition by id) > 1 
        then 'A' 
        else 'B' 
    end label
from mytable t
...