#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