2014-02-14 4 views
4

У меня есть таблица, которая имеет метки и некоторые коды рядом с ними:SQL выбрать верхние счетчики для сгруппированных строк

id | label | code 
1 | foo | 21 
2 | foo | 33 
3 | foo | 33 
4 | foo | 13 
5 | foo | 13 
6 | foo | 33 
7 | bar | 13 
8 | bar | 13 
9 | bar | 33 
10 | smt | 33 
11 | smt | 13 

Я нужен запрос, который выбирает верхние частоты «Код» для каждой «этикетки» , Вот то, что я до сих пор:

SELECT count(*) frequency, label, code 
FROM myTable 
GROUP BY label, code 

Это дает мне:

frequency | label | code 
1   | foo | 21 
3   | foo | 33 
2   | foo | 13 
2   | bar | 13 
1   | bar | 33 
1   | smt | 33 
1   | smt | 13 

То, что я хотел бы, хотя это:

frequency | label | code 
3   | foo | 33 
2   | bar | 13 
1   | smt | 33 
1   | smt | 13 

Как вы можете видеть только верхние частоты выбраны для 'foo' и 'bar'. Поскольку «smt» не имеет максимальной частоты как таковой (все одинаковы), все строки включены.
У меня нет идеи, даже с чего начать. Кто-нибудь может помочь? Благодарю. (Я использую MSSQL, кстати)

ответ

2

Моя подобное решение, как @ TechDo, но с одним подзапросом

SELECT frequency,label,code FROM 
(
    SELECT 
    count(*) AS frequency 
    ,MAX(COUNT(*)) OVER (PARTITION BY label) AS Rnk 
    ,label 
    ,code 
    FROM myTable 
    GROUP BY label, code 
) x 
WHERE frequency=Rnk 
ORDER BY frequency DESC 

SQLFiddle here

+0

благодарит за лучшее решение для моих нужд :) –

-1

несколько,

with cte as 
(SELECT count(*) frequency, label, code 
FROM myTable 
GROUP BY label, code 
) 
,cte1 as 
(
Select *,ROW_NUMBER()over order(partition by label order by frequency)rn1 
) 

select * from cte1 where rn=1 
+2

почти правильно, на самом деле вам нужно RANK() вместо ROW_NUMBER() из-за связей в RANK, что также будет выводиться – NickyvV

2

Пожалуйста, попробуйте:

SELECT * FROM(
    SELECT *, 
     MAX(frequency) OVER(PARTITION BY label) Col1 
    FROM(
     SELECT count(*) frequency, label, code 
     FROM myTable 
     GROUP BY label, code 
    )x 
)xx 
WHERE frequency=Col1 
+0

внутренний подзапрос не является необходимым, но еще допустимое решение , – NickyvV

0

Используя запрос и RANK():

SELECT frequency, label, code FROM 
(
    SELECT frequency, label, code, RANK() OVER(PARTITION BY code ORDER BY frequency DESC) [rank] 
    FROM (
     SELECT count(*) frequency, label, code 
     FROM myTable 
     GROUP BY label, code 
    ) Counts 
) Ranked 
WHERE [rank] = 1 
ORDER BY frequency DESC 
Смежные вопросы