Топ-N за десятилетие за последующие десятилетия (на SQL серверов) - PullRequest
1 голос
/ 08 мая 2020

Я пытаюсь получить ранжированный список Top 5 (т. Е. Наиболее распространенных) заголовков документов, сгруппированных по десятилетию, для каждого из 6 последних десятилетий.

Заголовки документов не уникальны . В каждом календарном году могут быть десятки или даже сотни документов с одинаковым названием.

Насколько я смог найти, следующий запрос go. Он дает мне 5 лучших титулов, но только для «всех остальных» Десятилетия.

Как мне изменить запрос, чтобы получить 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

1 Ответ

1 голос
/ 08 мая 2020

Если я правильно следил за вами, вы хотите попасть в топ 5 за десятилетие . Если так:

  • вам потребуется group by декада, а не календарный год, чтобы получить правильные подсчеты; легче вычислить десятилетие в подзапросе, поэтому вам не нужно повторять выражение case

  • ранг должен вычисляться по decade разделам, а не за год

  • затем вы можете использовать этот столбец для фильтрации во внешнем запросе

Учитывайте:

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 сервер допускает это, одинарные кавычки должны быть зарезервированы для литеральных укусов, как определено в стандарте SQL) - еще лучше, вы можете использовать идентификаторы, которые не требуют заключения в кавычки

  • в многотабличном запросе, всегда уточняйте все имена столбцов с таблицей, к которой они принадлежат; Я сделал несколько предположений здесь

  • , если у вас нет null значений в столбце documentTitle, которые вы не хотите учитывать, вы можете использовать count(*) вместо count(documentTitle) - это просто и эффективнее

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...