简体   繁体   中英

How to select a single record per group based on multiple MAX conditions?

I've got 2 tables:

workouts
id,    name, difficulty_level, rounds_count, some other columns...
 1,     'a',                1,            1
 2,     'a',                1,            5
 3,     'a',                2,            1
 4,     'a',                2,            5

 5,     'b',                1,            1 
 6,     'b',                1,            5
 7,     'b',                2,            1
 8,     'b',                2,            5

trainings
id, user_id,       workout_id,   created_at, some other columns...
 1,       1,                6,   2014-07-06
 2,       1,                1,   2014-07-07
 3,       1,                4,   2014-07-08
 4,       1,                7,   2014-07-09

Here's SQL Fiddle with this data: http://sqlfiddle.com/#!15/1d12d

I'd like to find the "hardest" workout for each workout name that was ever performed by given user. By "the hardest" I mean workout that has the highest difficulty level and the highest rounds count for that difficulty level. In the example given above I should get workout records with ids 4 and 7.

There's also another possible way to solve it. The whole idea of finding the "hardest" workout per given workout name is to prevent creating new trainings for given user with "easier" workouts than those already performed. Thus, assuming that it works correctly, the last training for given workout name should always point to the "hardest" workout so far.

I'm using PostgreSQL 9.3.

SQL Fiddle

select distinct on (user_id, name)
    user_id, name, w.id as workout_id,
    difficulty_level, rounds_count
from
    workouts w
    inner join
    trainings t on t.workout_id = w.id
order by user_id, name, difficulty_level desc, rounds_count desc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM