Группировать по и извлекать столбец, которого нет в предложении group by

#sql #postgresql

#sql #postgresql

Вопрос:

У меня есть (образец) данных:

 equipment_id | node_id | value (type: jsonb)
------------------------------
1            | 1       | 0.3
1            | 2       | 0.4
2            | 3       | 0.7
2            | 4       | 0.6
2            | 5       | 0.7
  

И я хочу получить строки, которые имеют максимальное значение в пределах одного и того же equipment_id:

 equipment_id | node_id | value
------------------------------
1            | 2       | 0.4
2            | 3       | 0.7
2            | 5       | 0.7
  

Есть запрос, который выполняет то, что я хочу, но я боюсь снижения производительности из-за преобразования jsonb в float:

 with cte as (
    select
       equipment_id,
       max(value::text::float) as val
    from metrics
    group by equipment_id
)
select cte.equipment_id, m.node_id, cte.val
from cte
join metrics m on cte.equipment_id = m.equipment_id and cte.val = m.value::text::float
  

Как я могу избежать кастинга?

Комментарии:

1. Действительно (1, 1, 0.4)?

2. Моя ошибка. Исправлено. Спасибо

Ответ №1:

Использовать distinct on :

 select distinct on (equipement_id) m.*
from metrics m
order by equipment_id, value desc;
  

Если ваше значение фактически хранится в виде строки, то используйте:

 order by equipment_id, value::numeric desc;
  

Ответ №2:

Вы можете использовать row_number()

 select * from
(
select *, row_number() over(partition by equipment_id order by value::text::float desc) as rn
from tablename
)A where rn=1