Запрос только записей с максимальным значением в группе - PullRequest
0 голосов
/ 07 ноября 2018

Скажем, у вас есть следующая таблица users в PostgreSQL:

id | group_id |    name | age
---|----------|---------|----
 1 |        1 |    adam |  10
 2 |        1 |     ben |  11
 3 |        1 | charlie |  12   <-
 3 |        2 |  donnie |  20  
 4 |        2 |    ewan |  21   <-
 5 |        3 |    fred |  30   <-

Как я могу запросить все столбцы только у самого старого пользователя для group_id (отмеченного стрелкой)?

Я пробовал с group by, но продолжаю нажимать "users.id" must appear in the GROUP BY clause.

(Примечание: мне нужно обработать запрос в области действия модели Rails AR.)

Ответы [ 3 ]

0 голосов
/ 07 ноября 2018

вы можете использовать подзапрос с агрегированным результатом в соединении

select m.* 
from  users m
inner join (
  select  group_id, max(age) max_age
  from users 
  group by group_id
) AS t on (t.group_id = m.group_id and t.max_age  = m.age)
0 голосов
/ 07 ноября 2018

После некоторых копаний вы можете использовать PostgreSQL DISTINCT ON (col):

select distinct on (users.group_id) users.*
from users
order by users.group_id, users.age desc;
-- you might want to add extra column in ordering in case 2 users have the same age for same group_id

В переводе в Rails это будет:

User
  .select('DISTINCT ON (users.group_id), users.*')
  .order('users.group_id, users.age DESC') 

Некоторые документы о DISTINCT ON: https://www.postgresql.org/docs/9.3/sql-select.html#SQL-DISTINCT

Рабочий пример: https://www.db -fiddle.com / f / t4jeW4Sy91oxEfjMKYJpB1 / 0

0 голосов
/ 07 ноября 2018

Вы можете использовать ROW_NUMBER/RANK (если возможна связь) оконных функций:

SELECT * 
FROM (SELECT *,ROW_NUMBER() OVER(PARTITION BY group_id ORDER BY age DESC) AS rn
      FROM tab) s
WHERE s.rn = 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...