Преобразование Dense_Rank Oracle в PostgresSQL

#oracle #postgresql #max #greatest-n-per-group #window-functions

#Oracle #postgresql #макс #наибольшее число пользователей на группу #окно-функции

Вопрос:

У меня есть оператор select, который содержит функцию dense_rank, написанную на Oracle, но мне не удается понять, как сделать ее совместимой с postgressql (версия 11.x)

 SELECT facility_id_fk, max(inspection_date) as last_inspection,
               max(inspection_type) keep (dense_rank first order by inspection_date desc) as inspection_type
FROM facility_inspections
GROUP BY facility_id_fk
  

Этот запрос выдает мне последнюю проверку и какой тип была эта последняя проверка:

 -------------------------------------------------
facility id | inspection date | inspection type 
-------------------------------------------------
93              04/28/2020        FULL
94              04/28/2020        LIMITED
-------------------------------------------------
  

Я пробовал следующее, но в нем отсутствует описание типа проверки, которое мне нужно, и по-прежнему предоставляет дубликаты, и, глядя на столбец ранга, похоже, что он ранжирует все проверки в таблице, а не для конкретного объекта

 SELECT facility_id_fk, max(inspection_date) as last_inspection,
      dense_rank () OVER (
           PARTITION BY inspection_type
           ORDER BY inspection_date DESC
           ) rank_order
FROM facility_inspections
GROUP BY facility_id_fk, inspection_date, inspection_type
  

Ответ №1:

В Postgres вы можете сделать это с помощью удобного расширения distinct on :

 select distinct on (facility_id_fk) *
from facility_inspections
order by facility_id_fk, inspection_date desc
  

Если бы вы должны были сделать это с помощью оконных функций, которые гораздо более переносимы, чем синтаксисы, специфичные для конкретного поставщика, такие как Oracle keep или Postgres distinct on , вы могли бы сформулировать запрос как:

 select *
from (
    select f.*, row_number() over(partition by facility_id_fk order by inspection_date desc) rn
    from facility_inspections f
) f
where rn = 1
  

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

1. Спасибо @GMB — это почти привело меня к этому. Мне просто нужно было учитывать значения null (я предполагаю, что Oracle сделал это автоматически) и сузить количество возвращаемых столбцов. Большое спасибо