У меня есть такой набор данных:

    story_name     | users  | age | reading_counts
-------------------+--------+-----+----------------
 Humpty Dumpty     | Elaine |   5 |             10
 Wheels on the Bus | Simon  |   3 |             15
 Dr.Seuss          | Simon  |   3 |             12
 asd               | Simon  |   3 |             10
 dsf               | Simon  |   3 |              6
 Dr.Seuss          | Elaine |   5 |              3
 asd               | Elaine |   5 |              7
(7 rows)

Я хочу иметь возможность написать запрос для отображения максимального количества чтения для каждого уникального пользователя. Так что-то вроде этого:

        story_name     | users  | reading_counts
-------------------+--------+----------------
 Humpty Dumpty     | Elaine |             10
 Wheels on the Bus | Simon  |             15

Пока у меня есть такой запрос:

SELECT story_name, users, reading_counts
FROM story
WHERE reading_counts IN (SELECT MAX(reading_counts) FROM story GROUP BY users);

И я получаю такой результат:

        story_name     | users  | reading_counts
-------------------+--------+----------------
 Humpty Dumpty     | Elaine |             10
 Wheels on the Bus | Simon  |             15
 asd               | Simon  |             10
(3 rows)
1
The Dodo 17 Окт 2019 в 22:30

2 ответа

Вы можете использовать оконную функцию rank() в подзапросе, чтобы присвоить рейтинг каждой записи в группах записей, имеющих одного и того же пользователя, упорядочить по убыванию счетчика чтения, а затем отфильтровать верхнюю запись в каждой группе во внешнем запросе:

select story_name, users, reading_counts
from (
    select 
        t.*,
        rank() over(partition by users order by reading_counts desc) rn 
    from mytable t
) x
where rn = 1

Примечание: если у данного пользователя есть лидирующие позиции (т. Е. Несколько записей с одинаковым максимальным счетчиком чтения), все они будут возвращены.

Другое решение, которое могло бы предложить лучшую производительность, - использовать коррелированный подзапрос для фильтрации, например:

select story_name, users, reading_counts
from mytable t
where reading_counts = (
    select max(reading_counts) from mytable t1 where t1.users = t.users
)

Этот запрос будет использовать индекс по users.

0
GMB 17 Окт 2019 в 22:34

Вы можете использовать подзапрос для max для каждого пользователя и присоединиться

  SELECT story_name, users, reading_counts
  FROM story
  INNER JOIN  (
    SELECT user, MAX(reading_counts) max_x_user 
    FROM story 
    GROUP BY users 
  ) t on t.user  = story.user and story.reading_counts = t.max_x_user 
0
scaisEdge 17 Окт 2019 в 22:36