Reputation: 297
I have data like this:
some_data, p_column, type
pla, 1, a
bla, 1, b
sth, 1, a
sth, 2, a
Than lets say I partition by p_column over some descending dates in some_data and with rank I get:
some_data, p_column, type, rank
pla, 1, a, 1
bla, 1, b, 2
sth, 1, a, 3
sth, 2, a, 1
For each partition I want to select row with the lowest rank where the type is b, else if there is no row with type b in the partition I want to select row with the lowest rank with type a.
So I will get rows (for the example):
some_data, p_column, type, rank
bla, 1, b, 2
sth, 2, a, 1
If this is not clear, I attach pseudocode:
for each partition:
if type b is in partition:
select row b with lowest rank
else:
select row a with lowest rank
Upvotes: 1
Views: 1150
Reputation: 520958
One conceptual way of approaching this is to realize that you really want a double partition here, one layer for the p_column
and a second layer for the type
. Based on your precedence rules, you want to give the b
type a higher priority than a
. So we can partition on the p_column
followed by the type
, and then use row number again to choose the lowest record for each partition.
SELECT some_data, p_column, type
FROM
(
SELECT some_data, p_column, type,
ROW_NUMBER() OVER (PARTITION BY p_column
ORDER BY CASE WHEN type = 'b' THEN 0 ELSE 1 END) rn
FROM
(
SELECT some_data, p_column, type,
RANK() OVER (PARTITION BY p_column, type ORDER BY some_date_col) rank
FROM yourTable
) t
WHERE t.rank = 1
) t
WHERE t.rn = 1
ORDER BY p_column;
Upvotes: 3