Reputation: 1320
I want to get the "max" character value for a column using a group by statement, except instead of the default alphabetical order, I want to set up a custom ordering that the max will use.
Table1:
ID | TYPE
-----+-------
1 | A
1 | B
1 | C
2 | A
2 | B
I want to group by ID and get max(type) in the order of C, A, B. Expected result:
ID | MAX_TYPE
-----+-----------
1 | C
2 | A
Upvotes: 6
Views: 3355
Reputation: 17915
select
id,
case
max(
case max_type
when 'C' then 3 when 'A' then 2 when 'B' then 1
end
)
when 3 then 'C' when 2 then 'A' when 1 then 'B'
end as max_type
from T
group by id
Translate to a value that an be ranked by max()
and then translate back to the original value.
If you also want to order the result by that value then you could add:
order by
max(
case max_type
when 'C' then 3 when 'A' then 2 when 'B' then 1
end
) desc
Some platforms require the sorting column to be included in the output. I'm not sure if PostgreSql is one of those. And no objection to Gordon's answer but you'd have to use another window function to calculate the sort order if you need that too.
Upvotes: 10
Reputation: 1269623
Instead of translating back and forth, use window functions:
select t.*
from (select t.*,
row_number() over (partition by id
order by (case when type = 'C' then 1
when type = 'A' then 2
when type = 'B' then 3
end) as seqnum
from t
) t
where seqnum = 1;
Depending on what the values look like, you can also simplify this using string functions:
select t.*
from (select t.*,
row_number() over (partition by id
order by position(type, 'CAB')) as seqnum
from t
) t
where seqnum = 1;
Upvotes: 3