My tables looks like this:
For each TimeOfDay I would like to get the most frequent Category. For example if there are 3 auctions with unique ClosedTime but each of this Time has TimeOfDay=1 and 2 of these auctions have CategoryId=1 and one auction CategoryId=2 I would like to get:
TimeOfDay | CategoryId
1 | 1
I have tried group by TimeOfDay and CategoryId but still I don't know how to get top category for each TimeOfDay group. I have this:
select t.TimeOfDay, a.CategoryId, count(a.CategoryId)
numberOfSalesInCategory
from Auction a
join Time t on t.Id = a.ClosedTime
where IsSuccess = 1
group by t.TimeOfDay, a.CategoryId
and result for some sample data:
TimeOfDay | CategoryId | numberOfSalesInCategory
0 1 1
1 1 1
1 2 3
2 2 1
0 3 1
3 3 1
3 4 2
So for these data I would like to get:
TimeOfDay | CategoryId
0 | 1 or 3 numberOfSalesInCategory for both is 1
1 | 2 numberOfSalesInCategory is 3
2 | 2 only one category
3 | 4 numberOfSalesInCategory is 2
Technically, you are looking for the mode. There can be multiple modes, if multiple values all have the same frequency. If you are happy to arbitrarily choose one, then a conditional aggregation with row_number()
is the solution:
select TimeOfDay,
max(case when seqnum = 1 then CategoryId end) as ModeCategory
from (select t.TimeOfDay, a.CategoryId, count(*) as numberOfSalesInCategory,
row_number() over (partition by t.TimeOfDay order by count(*) ) as seqnum
from Auction a join
Time t
on t.id = a.ClosedTime
where a.isSuccess = 1
group by t.TimeOfDay, a.CategoryId
) ta
group by TimeOfDay;
You could put the current statement in a CTE, rank them with RANK() and then do a stuff statement.
eg
; WITH T AS (SELECT t.TimeOfDay, a.CategoryId, COUNT(a.CategoryId)
numberOfSalesInCategory
FROM Auction a
JOIN Time t ON t.Id = a.ClosedTime
WHERE IsSuccess = 1
GROUP BY t.TimeOfDay, a.CategoryId)
, S AS (SELECT T.*
, RANK() OVER (PARTITION BY TimeOfDay ORDER BY numberOfSalesInCategory DESC) RankOrder
FROM T)
SELECT DISTINCT TimeOfDay
, STUFF(((SELECT ' or ' + CONVERT(NVARCHAR, CategoryId)
FROM S
WHERE RankOrder = 1
AND TimeOfDay = BloobleBlah.TimeOfDay
FOR XML PATH('')), 1, 4, '') CategoryId
FROM S BloobleBlah
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.