Элегантный подход к получению первого значения из каждой группы без использования внешнего запроса

Я пытаюсь получить первое значение из каждой группы моих данных. Однако мне не нравится использовать предложение внешнего запроса / with. Не могли бы вы сообщить мне, как я могу написать это элегантно, не используя внешний запрос?

Я использовал внешний запрос для получения первого значения из каждой группы. Однако не могли бы вы помочь мне написать это элегантным образом в том же sql. Есть ли какая-нибудь функция, такая как Max, Min, которая даст нам первое значение, чтобы мне не приходилось писать этот внешний запрос

select * 
from (    
  select subject_id,hadm_id,
         rank() OVER (PARTITION BY subject_id ORDER BY row_id) AS BG_CG_number 
  from labevents
  where itemid in ('50809','50931','51529') 
    AND valuenum > 110 
    and hadm_id is not null
) t1 
where t1.bg_cg_number = 1

Найдите на снимке экрана ниже текущий и ожидаемый результат  введите описание изображения здесь


person The Great    schedule 03.04.2019    source источник
comment
Что не так с подзапросом?   -  person a_horse_with_no_name    schedule 03.04.2019
comment
Есть ли другой способ написать это? Как и функция Max, Min, которая может помочь нам получить first_value? Хотите знать, есть ли другой простой / элегантный способ писать?   -  person The Great    schedule 03.04.2019


Ответы (1)


В производной таблице (или подзапросе) нет ничего плохого.

Собственный distinct on () Postgres обеспечивает то же самое и обычно быстрее, чем использование оконной функции (это не из-за производной таблицы, а из-за оконной функции):

Цитата из руководства

SELECT DISTINCT ON ( expression [, ...] ) сохраняет только первую строку каждого набора строк, в которых данные выражения оцениваются как равные. Выражения DISTINCT ON интерпретируются с использованием тех же правил, что и для ORDER BY (см. Выше).

Обратите внимание, что «первая строка» каждого набора непредсказуема, если только ORDER BY не используется, чтобы гарантировать, что нужная строка появится первой.

Таким образом, ваш запрос можно переписать на:

select distinct on (subject_id) subject_id, hadm_id
from labevents
where itemid in ('50809','50931','51529') 
  AND valuenum > 110 
  and hadm_id is not null
order by subject_id, row_id;
person a_horse_with_no_name    schedule 03.04.2019
comment
Есть ли разница между отличным и отличным? Я также могу использовать разные, чтобы получить по одной уникальной строке для каждого предмета. Верно? - person The Great; 03.04.2019
comment
@SELVA: distinct работает со всеми столбцами в списке выбора, distinct on (..) только с указанными. - person a_horse_with_no_name; 03.04.2019
comment
Хорошо. Но когда мы можем использовать разные и разные, чтобы легко получить первую строку, почему мы должны использовать функцию Rank ()? Используется ли функция Rank (), когда мы хотим получить записи определенного ранга? В чем преимущество использования Rank () перед этими двумя разными и разными методами? - person The Great; 03.04.2019
comment
Если моя цель - получить 1-ю запись из каждой группы, не могли бы вы порекомендовать мне использовать отдельный / отличный от (на основе моих условий col) по рангу (), плотному рангу () - person The Great; 03.04.2019
comment
Помогите мне с этим, пожалуйста? stackoverflow.com/questions/60964182/ - person The Great; 01.04.2020