Для данного пользователя выберите пользователя с наиболее распространенными оценками. - PullRequest
0 голосов
/ 14 марта 2012

Скажите, у меня есть таблица оценок:

create table ratings (
    user_id int unsigned not null,
    post_id int unsigned not null,
    rating set('like', 'dislike') not null,
    primary key (user_id, post_id)
);

И для данного пользователя с id 1, как я могу выбрать пользователя, у которого больше лайков? А пользователь с большим количеством общего не любит? А пользователь с большим рейтингом (любит или не любит) общего? Я думаю, что запросы были бы очень похожи, но я пока не могу понять ни одного из них. Я буду обновлять с любым прогрессом, который я делаю.

Любая помощь приветствуется, спасибо!

Ответы [ 4 ]

1 голос
/ 14 марта 2012

Попробуйте:

select r2.user_id from (
  select post_id, rating from ratings,
    (select @userId := 2) init
  where user_id = @userId
) as r1
join ratings r2
on r1.post_id = r2.post_id and r1.rating = r2.rating
where r2.user_id != @userId and r2.rating = 'like'
group by r2.user_id
order by count(*) desc
limit 1

Это должно работать на лайки и антипатии, изменяя строку. А чтобы изменить пользователя, просто измените назначение переменной.

Следующее должно работать как для антипатий, так и для лайков (просто удалив условие фильтрации):

select r2.user_id from (
  select post_id, rating from ratings,
    (select @userId := 2) init
  where user_id = @userId
) as r1
join ratings r2
on r1.post_id = r2.post_id and r1.rating = r2.rating
where r2.user_id != @userId
group by r2.user_id
order by count(*) desc
limit 1
1 голос
/ 14 марта 2012
select
    r1.user_id as user1
    ,r2.user_id as user2
    ,r1.rating as rating
    ,count(*) as num_matching_ratings
from
    ratings r1 
    inner join ratings r2
        on r1.post_id = r2.post_id 
            and r1.rating = r2.rating
            and r1.user_id <> r2.user_id --don't want to count
                                         --matches with self
where
    r1.user_id = 1 -- change this to any user, or use a
                   -- variable to increase reusebility
    and r1.rating = 'like' -- set this to dislike to common dislikes
group by
    r1.user_id
    ,r2.user_id
    ,r1.rating
having
    count(*) > 1 --show only those with more than 1 in common
order by
    count(*) desc
/* limit 1 -- uncomment to show just the top match */

Объединяя таблицы, мы можем подсчитать количество случаев, когда второй пользователь оценил статью аналогичным образом.Этот запрос вернет оценку от наиболее общего к наименьшему.Если вы раскомментируете оператор «limit 1», он вернет совпадение только с наиболее общими.

0 голосов
/ 15 марта 2012

Опираясь на ответы Криса и Мостачо, я сделал следующий запрос. Я не уверен на 100%, что это работает каждый раз, но я еще не нашел недостаток.

select r2.user_id
from ratings r1
join ratings r2
on r1.user_id <> r2.user_id
and r1.post_id = r2.post_id 
and r1.rating = r2.rating
where r1.user_id = 1 
and r1.rating = 'like'
group by r2.user_id
order by count(r2.user_id) desc
limit 1

Этот запрос возвращает идентификатор пользователя с более общими лайками у пользователя 1. Чтобы получить пользователя с более общими оценками, просто удалите and r1.rating = 'like' из предложения where.

0 голосов
/ 14 марта 2012

простите мой синтаксис, я не очень часто пишу raw sql.вы можете рассмотреть этот псевдокод.

сначала я получу таблицу с идентификатором 1

view1 = SELECT * FROM ratings, WHERE ( user_id = 1)

, затем присоединюсь к ней с оценками

view2 = select * from view1, ratings, where(view1.rating = ratings.rating AND view1.post_id = records.post_id)

затем я собрал бы число

view3 = select count from view2 group by (user_id)

и затем я получил бы максимум этого.

Теперь это всего лишь алгоритмический обзор моих первых мыслей.Я не думаю, что это будет особенно эффективно, и вы, вероятно, не будете использовать этот синтаксис.

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