2015-12-01 2 views
1

Мои таблицы выглядит следующим образом:T-SQL группы по 2 таблицы

enter image description here

Для каждого TimeOfDay я хотел бы получить наиболее часто категорию. Например, если есть 3 аукциона с уникальным ClosedTime, но каждый из этого времени имеет TimeOfDay = 1 и 2 из этих аукционов имеют CategoryId = 1 и один аукцион CategoryId = 2 Я хотел бы получить:

TimeOfDay | CategoryId 
1   | 1 

Я попытался group by TimeOfDay и CategoryId, но все же я не знаю, как получить верхнюю категорию для каждой группы TimeOfDay. У меня есть это:

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 

и привести к некоторой выборки данных:

TimeOfDay | CategoryId | numberOfSalesInCategory 
0   1    1 
1   1    1 
1   2    3 
2   2    1 
0   3    1 
3   3    1 
3   4    2 

Так что для этих данных я хотел бы получить:

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 

ответ

0

Вы можете поместить текущее выражение в CTE, ранжируйте их с помощью RANK(), а затем произведите инструкцию.

например.

; 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 
1

Технически вы ищете режим. Могут быть несколько режимов, если несколько значений имеют одинаковую частоту. Если вы с удовольствием произвольно выбираете один из них, то условная агрегация с row_number() является решением:

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;