连续几十年按十年排列的前N名(在SQL Server中)

连续几十年按十年排列的前N名(在SQL Server中),sql,sql-server,group-by,greatest-n-per-group,window-functions,Sql,Sql Server,Group By,Greatest N Per Group,Window Functions,我正试图获得最近6个十年中每一个十年排名前5名的列表,即最常见的文档标题 文档标题是非唯一的。在任何给定的日历年中,可能有几十个甚至数百个具有相同标题的文档 下面的查询是我所能做的。它给了我前五名的头衔,但只适用于“所有其他人”的十年 我如何修改查询以获得其他十年的前五名 SELECT Top 5 documentTitle AS 'Title', RANK() OVER (PARTITION BY calendarYear ORDER BY COUNT(documentTitl

我正试图获得最近6个十年中每一个十年排名前5名的列表,即最常见的文档标题

文档标题是非唯一的。在任何给定的日历年中,可能有几十个甚至数百个具有相同标题的文档

下面的查询是我所能做的。它给了我前五名的头衔,但只适用于“所有其他人”的十年

我如何修改查询以获得其他十年的前五名

SELECT
    Top 5 documentTitle AS 'Title',
    RANK() OVER (PARTITION BY calendarYear ORDER BY COUNT(documentTitle) DESC) AS Rank,
    COUNT(tblDocumentFact.inventionTitleEnID) AS 'Number of Occurrences',
    CASE
        WHEN calendarYear BETWEEN 2010 AND 2019 THEN '2010 - 2019'
        WHEN calendarYear BETWEEN 2000 AND 2009 THEN '2000 - 2009'
        WHEN calendarYear BETWEEN 1990 AND 1999 THEN '1990 - 1999'
        WHEN calendarYear BETWEEN 1980 AND 1989 THEN '1980 - 1989'
        WHEN calendarYear BETWEEN 1970 AND 1979 THEN '1970 - 1979'
        WHEN calendarYear BETWEEN 1960 AND 1969 THEN '1960 - 1969'
        ELSE 'all others'
    END AS Decade
FROM        tbldocumentTitleDimension
INNER JOIN  tblDocumentFact     ON  tbldocumentTitleDimension.documentTitleID   = tblDocumentFact.documentTitleID
INNER JOIN  tblDateDimension    ON  tblDocumentFact.publicationDateID           = tblDateDimension.dateID
GROUP BY    documentTitle,
            calendarYear
ORDER BY    [Number of Occurrences] DESC

如果我没记错的话,你想每十年排名前五。如果是:

你需要按十年而不是日历年进行分组,以获得正确的计数;在子查询中计算十年比较容易,因此不必重复大小写表达式

排名应按十年分区计算,而不是每年计算

然后可以使用该列在外部查询中进行筛选

考虑:

select *
from (
    select
        dtd.documenttitle as title,
        rank() over (partition by dd.decade order by count(*) desc) as rnk,
        count(*) as number_of_occurrences,
        dd.decade
    from tbldocumentTitleDimension dtd
    inner join tblDocumentFact df on dtd.documenttitleid   = df.documenttitleid
    inner join  (
        select 
            dateid,
            case
                when calendarYear between 2010 and 2019 then '2010 - 2019'
                when calendarYear between 2000 and 2009 then '2000 - 2009'
                when calendarYear between 1990 and 1999 then '1990 - 1999'
                when calendarYear between 1980 and 1989 then '1980 - 1989'
                when calendarYear between 1970 and 1979 then '1970 - 1979'
                when calendarYear between 1960 and 1969 then '1960 - 1969'
                else 'all others'
            end AS decade
            from tblDateDimension
    ) dd on df.publicationdateid  = dd.dateid
    group by dtd.documenttitle, dd.decade
) t
where rnk <= 5
order by decade, number_of_occurrences desc
旁注:

不要对标识符使用单引号尽管SQL Server允许,但单引号应该保留给普通的stings,正如SQL标准中定义的那样-更好的是,您可以使用不需要引用的标识符

在多表查询中,始终使用列名所属的表限定所有列名;我在这里做了一些假设

除非在documentTitle列中有不想计入的空值,否则可以使用count*而不是countdocumentTitle—这是直接的,而且效率更高


太好了,非常感谢。我也很感激你的旁注。我将研究它们,并尝试相应地改进我的SQL。我还看到您使用rnk作为列名而不是排名。Rank至少在我的查询中用作列名,但我现在意识到它的格式不好:SSMS pink将单词标记为保留,所以我应该抓住它。count*有效,因为documentTitle列中没有空值。再次感谢。