给定一个帖子X,选择所有帖子Y,使得没有评价他们的用户都喜欢他们

时间:2012-03-03 04:06:04

标签: mysql sql

假设一个名为'users'的表,一个名为'posts'的表和一个名为'ratings'的表,其中包含每个用户对每个帖子的评级(“喜欢”或“不喜欢”)。

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)
);

鉴于帖子X,我想选择所有帖子Y,以便没有用户对他们进行评分,两者都喜欢。此外,如果可能的话,我想按照对其进行评分的普通用户的数量来订购这些帖子,这意味着与X最常见的“评分者”的帖子Y应首先出现。

我复制了迄今为止我所做的事情,但我认为这一切都不值得。感谢任何帮助,谢谢!

2 个答案:

答案 0 :(得分:3)

试试this fiddle。我不是100%确定我得到了你想要的东西,但是......如果它适合的话,请检查你自己的数据。

您还可以删除WHERE并将X.post_id AS this_post_id添加到FROM以获取所有帖子。

答案 1 :(得分:2)

  

鉴于帖子X,我想选择所有帖子Y,以便没有评价他们的用户,都喜欢他们。

好的,所以给定以下数据集,当ID = 1时你会期望5和6(我知道你也不想显示ID = 1):

+---------+---------+---------+
| POST_ID | USER_ID | RATING  |
+---------+---------+---------+
|       1 |       1 | like    | // ID = 1, so remove this post
|       1 |       2 | like    |
|       1 |       3 | like    |
|       1 |       4 | dislike |
|       2 |       1 | like    | // Double like, so remove this post
|       2 |       2 | dislike |
|       2 |       3 | like    |
|       2 |       4 | dislike |
|       3 |       1 | like    | // Double like, so remove this post
|       4 |       1 | dislike |
|       4 |       2 | like    | // Double like, so remove this post
|       5 |       1 | dislike |
|       5 |       2 | dislike |
|       5 |       5 | dislike |
|       6 |       1 | dislike |
+---------+---------+---------+

此查询将为您提供:

select distinct post_id from ratings r3
where r3.post_id not in (
  select r2.post_id from ratings r1
  join ratings r2
  on r1.post_id <> r2.post_id and r1.user_id = r2.user_id
  where (r1.post_id = 1 or r2.post_id = 1) and r1.rating = 'like' and r2.rating = 'like'
)

如果您还希望它们按照常见的评估者排序,则运行此查询:

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

这是example