Reputation: 95
I have a table like this:
store | shelf | type | count |
---|---|---|---|
A | s1 | t1 | 3 |
A | s1 | t2 | 4 |
A | s2 | t3 | 2 |
A | s2 | t2 | 2 |
A | s3 | t4 | 1 |
A | s3 | t5 | 1 |
I want to know the dominant type per store per shelf. The rule is:
for each store and shelf:
if there's a max value of count for one type, the dominant would be this type. for store A shelf s1, it would be t2, because t2 > t1)
if there's tie, then check the count of the type for store total, and use whichever has a larger store total. for store A shelf s2, it would be t2, because total count of t2 (2 + 4) > total count of t3 (2)
if still a tie, will put dominant as "can't decide". for store A shelf s3, it would be "can't decide"
Sample output:
store | shelf | dominantType |
---|---|---|
A | s1 | t2 |
A | s2 | t2 |
A | s3 | can't decide |
Now I can achieve the first 2 rules with first calculating countStoreLevel
, then use ROW_NUMBER() OVER:
rank AS (
SELECT table.*, ROW_NUMBER() OVER (PARTITION BY store, shelf ORDER BY count DESC, countStoreLevel DESC) AS rn
FROM shopping)
SELECT * FROM rank WHERE rn = 1
But I don't know how to deal with rule 3, when there's a tie, and it should be can't decide.
Could anyone help me with it? Thanks a looooot!
Upvotes: 0
Views: 490
Reputation: 1270703
You can use window functions. The idea is:
type
by shelf and by store.'can''t decide'
.As a query, this looks like:
select t.*,
(case when min(case when seqnum_shelf = 1 then type end) over (partition by store, shelf) =
max(case when seqnum_shelf = 1 then type end) over (partition by store, shelf) =
then min(case when seqnum_shelf = 1 then type end) over (partition by store, shelf)
when min(case when seqnum_store = 1 then type end) over (partition by store) =
max(case when seqnum_store = 1 then type end) over (partition by store) =
then min(case when seqnum_store = 1 then type end) over (partition by store)
else 'can''t decide'
end) as dominantType
from (select t.*,
dense_rank() over (partition by store, shelf order by cnt_shelf desc) as seqnum_shelf,
dense_rank() over (partition by store order by cnt_shelf desc) as seqnum_store
from (select t.*,
count(*) over (partition by store, shelf, type) as cnt_shelf,
count(*) over (partition by store, type) as cnt_store
from t
) t;
Upvotes: 1