2015-09-19 4 views
0

У меня есть этот запрос для извлечения строк из SQL Server таблицы:Как получить желаемое количество строк для каждой группы/категории в SQL Server

SELECT 
    aid, 
    research_area_category_id, 
    CAST(research_area as VARCHAR(100)) [research_area], 
    COUNT(*) [Paper_Count] 
FROM 
    sub_aminer_paper 
GROUP BY 
    aid, 
    research_area_category_id, 
    CAST(research_area as VARCHAR(100)) 
HAVING 
    aid IN (SELECT 
       aid 
      FROM 
       sub_aminer_paper 
      GROUP BY 
       aid 
      HAVING 
       MIN(p_year) = 1990 AND MAX(p_year) = 2014 AND COUNT(pid) BETWEEN 10 AND 40 
      ) 
ORDER BY aid ASC, Paper_Count DESC 

, который возвращает этот вывод:

aid  research_area_category_id research_area    Paper_Count 
2937 33       markov chain     3 
2937 33       markov decision process  1 
2937 1       optimization problem   1 
2937 27       real time application  1 
2937 32       software product lines  1 
11120 29       aspect oriented programming 4 
11120 1       graph cut     2 
11120 1       optimization problem   2 
11120 32       uml class diagrams   1 
11120 25       chinese word segmentation 1 
11120 29       dynamic programming   1 
11120 19       face recognition    1 
11120 1       approximation algorithm  1 
12403 2       differential equation  7 
12403 1       data structure    2 
12403 34       design analysis    1 
12403 9       object detection    1 
12403 27       operating system    1 
12403 1       problem solving    1 
12403 21       archiving system    1 
12403 2       calculus      1  

Теперь это возвращает выход, включая все строки, соответствующие соответствующим aid, тогда как мне нужно только первые 3 строки для каждого aid ORDER BY Paper_Count DESC, то есть строки, содержащие значение Paper_Count3, 1, 1 для aid2937, 4,2,2 для 11120 и 7,2,2 для 12403.

Пожалуйста, помогите! Благодарю.

+0

Используйте КТР с DENSE_RANK OVER .. – Mihai

ответ

1

один способ заключается в применении row_number() over(partition by aid order by Paper_Count desc) as rn на вашем результирующем, а затем выбрать все записи с rn<=3

with cte 
as 
(
SELECT 
    aid, 
    research_area_category_id, 
    CAST(research_area as VARCHAR(100)) [research_area], 
    COUNT(*) [Paper_Count] 
FROM 
    sub_aminer_paper 
GROUP BY 
    aid, 
    research_area_category_id, 
    CAST(research_area as VARCHAR(100)) 
HAVING 
    aid IN (SELECT 
       aid 
      FROM 
       sub_aminer_paper 
      GROUP BY 
       aid 
      HAVING 
       MIN(p_year) = 1990 AND MAX(p_year) = 2014 AND COUNT(pid) BETWEEN 10 AND 40 
      ) 
ORDER BY aid ASC, Paper_Count DESC 
) 
, 
cte1 
AS 
( 
    SELECT * , 
    ROW_NUMBER() OVER (PARTITION BY aid ORDER BY Paper_Count DESC) AS rn 
    FROM cte 
) 

SELECT * FROM cte1 WHERE rn<=3 
+0

row_number возвратит дубликаты, если paper_count тот же – Mihai

+0

@Mihai Нет, это не возвращая дубликаты даже для того же самого Paper_Count, что и для самой первой «помощи», то есть '2937',' Paper_Count' одинаково. – maliks

+0

@Taufel. Вы прав. Я не знаю, почему я смутил его с помощью RANK() – Mihai