Postgresql витягує останній рядок для кожного ідентифікатора


81

Припустимо, я маю наступні дані

  id    date          another_info
  1     2014-02-01         kjkj
  1     2014-03-11         ajskj
  1     2014-05-13         kgfd
  2     2014-02-01         SADA
  3     2014-02-01         sfdg
  3     2014-06-12         fdsA

Я хочу для кожного витягу ідентифікатора останню інформацію:

  id    date          another_info
  1     2014-05-13         kgfd
  2     2014-02-01         SADA
  3     2014-06-12         fdsA

Як я міг цим керувати?

Відповіді:


156

Найефективніший спосіб - використовувати distinct onоператор Postgres

select distinct on (id) id, date, another_info
from the_table
order by id, date desc;

Якщо вам потрібне рішення, яке працює в усіх базах даних (але є менш ефективним), ви можете використовувати функцію вікна:

select id, date, another_info
from (
  select id, date, another_info, 
         row_number() over (partition by id order by date desc) as rn
  from the_table
) t
where rn = 1
order by id;

Рішення з функцією вікна в більшості випадків швидше, ніж використання підзапиту.


4
проголосував! йому потрібен індекс за датою, хоча я завжди припускаю, що індекси можна шукати в обох напрямках, індекс первинного ключа за зростанням за замовчуванням повинен добре працювати для спадного в тому самому полі, у моєму випадку у мене є складені ключі (ідентифікатор, дата) складені клавіші, що викликають проблеми?
PirateApp

20
select * 
from bar 
where (id,date) in (select id,max(date) from bar group by id)

Тестується в PostgreSQL, MySQL


-5

Групуйте за ідентифікатором та використовуйте будь-які сукупні функції, щоб відповідати критеріям останнього запису. Наприклад

select  id, max(date), another_info
from the_table
group by id, another_info

4
знову це не дасть фактичного результату
Vivek S.

Чого мені тут не вистачає?
Амаль Ц.

Ви розрізняєте групи за іншою інформацією, тому це не буде групуватися лише за ідентифікатором. І якщо замість цього ви використовуєте агрегатну функцію на another_info, щоб отримати правильне групування, тоді функція агрегування (скажімо, max ()) не поверне значення another_info для рядка, що має max (date). Дійсно, ці два спостереження є причиною того, що це питання насамперед.
gwideman
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.