简体   繁体   中英

T-SQL group by 2 tables

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.

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