Запрос Sql, чтобы получить лучшие 3 записи с максимальным количеством голосов в каждой категории - PullRequest
0 голосов
/ 19 ноября 2010

Нужна помощь в составлении этого запроса. Я использую Mysql

У меня есть две таблицы

Видео - содержит видео, загруженные пользователями

  • video_id
  • user_id
  • category_id

Голосование - содержит голос, отданный любым пользователем за конкретное видео

  • голосовать_ид
  • video_id
  • user_id

Я не хочу жестко кодировать категории в запросе - категории хранятся в таблице категорий, в которой есть category_id и category_name

Мне нужен запрос, который выбирает 3 лучших видео (с максимальным количеством голосов) для каждой категории.

Пример данных - видео таблица

video_id |  user_id  | category_id
   1          100          10
   2          101          10
   3          102          11
   4          103          11
   5          104          11
   6          105          11
   7          105          12

Пример данных - таблица голосования

vote_id  |  video_id |  user_id
  11           3          105
  12           3          102
  13           3          111
  14           3          121
  15           4          200
  16           4          201
  17           1          222

Пример данных - таблица категорий

category_id  |  category_name
   10               HipHop
   11               Rap
   12               Country

Ответы [ 2 ]

1 голос
/ 19 ноября 2010

Это тип проблемы, который тривиально решить с помощью функций ранжирования. Однако, поскольку MySQL еще не поддерживает их, это усложняет задачу. В этом проекте я предположил, что video_id был первичным ключом таблицы Video.

Select video_id, user_id, category_id, vote_count, vote_rank
From    (
        Select VoteCounts.video_id, VoteCounts.user_id
            , VoteCounts.category_id, VoteCounts.vote_count
            , (
                Select Count(*) + 1
                From    (
                        Select V1.video_id, V1.user_id, V1.category_id
                            , Count(vote_id) As vote_count
                        From Videos As V1
                            Left Join Votes As V2
                                On V2.video_id = V1.video_id
                        Group By V1.video_id, V1.user_id, V1.category_id
                        )  As VoteCounts1
                Where VoteCounts1.category_id = VoteCounts.category_id
                    And (
                        VoteCounts1.vote_count > VoteCounts.vote_count
                        Or (VoteCounts1.vote_count = VoteCounts.vote_count
                            And VoteCounts1.video_id < VoteCounts.video_id )
                        )
                ) As vote_rank
        From    (
                Select V1.video_id, V1.user_id, V1.category_id
                    , Count(vote_id) As vote_count
                From Videos As V1
                    Left Join Votes As V2
                        On V2.video_id = V1.video_id
                Group By V1.video_id, V1.user_id, V1.category_id
                )  As VoteCounts
        ) As VoteRanks
Where VoteRanks.vote_rank <= 3
0 голосов
/ 19 ноября 2010

Я не знаю о MySQL, но вот как я бы попытался сделать это в SQL Server, и, возможно, внес некоторые коррективы в зависимости от результатов, которые имеют смысл.

select Category
        , Film
        , MAX(Votes) as Votes
    from (
        select TOP 3 c.category_name as Category
                , vd.video_id as Film
                , COUNT(vt.votes) as Votes
            from Category c
                inner join Video vd on vd.category_id = c.category_id
                inner join Votes vt on vt.video_id = vd.video_id
            where c.category_id = 10 -- HipHop
            group by c.category_name
                , vd.video_id
        union
        select TOP 3 c.category_name
                , vd.video_id
                , COUNT(vt.votes) as Votes
            from Category c
                inner join Video vd on vd.category_id = c.category_id
                inner join Votes vt on vt.video_id = vd.video_id
            where c.category_id = 11 -- Rap
            group by c.category_name
                , vd.video_id
        -- You need as much UNION as there are categories.
    ) Top3VotesPerCategory
    group by Category
        , Film

В зависимости от того, принимаете ли вы отрицательные голоса по фильму, можно зарегистрировать отрицательный голос по фильму, и это не значит, что он рекомендует это видео. Если вы поддерживаете такую ​​функциональную функцию, то вы можете рассмотреть условное SUM() вместо COUNT() для количества голосов, чтобы учитывались отрицательные голоса и уменьшались бы его общие баллы в отношении голосов. .

...