我想从表中选择N个随机行,但在所有这些行中,特定值可能只出现X次。
表"评论":
*--------------------*
| ID | CODE_REVIEWER |
*--------------------*
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
*--------------------*
表"用户" (我遗漏了很多不重要的东西:
*----*
| ID |
*----*
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
*----*
示例输出: 对于X = 3:
*-----------*
| REVIEWER |
*-----------*
| 4 |
| 1 |
| 5 |
*-----------*
对于X = 2:
*-----------*
| REVIEWER |
*-----------*
| 1 |
| 5 |
| 3 |
*-----------*
对于X = 1(空):
*-----------*
| REVIEWER |
*-----------*
因此,它必须是一个ResultSet,其中包含一些与ID X不同的ID,但这些ID可能只出现在"表2"作为" code_reviewer" N次。 所以每个人都可以成为"评论家"对于3个人,可以由3个人审查
谢谢!
修改 这是我到目前为止所得到的:
select newid from (select id, count(*) as num from (select * from users
where id != ?) as users group by id order by RAND() LIMIT ?) as sb
where num < 3 and newid not in (select code_reviewer from reviews where id = ?)
它完美无缺,除此之外它有时会返回
*---*
| 2 |
| 1 |
| 2 |
*---*
(包含两次,不应该这样)
答案 0 :(得分:1)
不幸的是,我知道MSSQL而不是MySQL。我将尝试使用MSSQl进行回答,希望这将引导您朝着正确的方向前进。
我使用变量来确定应该返回多少行,然后使用一个简单的NEWID作为随机函数。 (据我所知,您可以在MySQL中订购RAND()而不是NEWID())
declare @userId int
select @userId = 1
declare @existingReviewCount int
select @existingReviewCount = COUNT(*) from Reviews where Id = @userId
declare @requiredRowCount int
select @requiredRowCount = 3 - @existingReviewCount
select top (@requiredRowCount) Id from Users
where @userId != Id
order by NEWID()
现在将@userId替换为1,它将返回一个空集。
答案 1 :(得分:1)
这似乎基本上是每组前n个问题。有几种方法可以解决这个问题。这是一种快速而肮脏的方式,它将为您提供所需的逗号分隔的ID列表。如果你想在你的代码中爆炸,你就可以了。
select u.*,
-- r_counts.cnt as reviews_count,
substring_index(
group_concat(u_rev.id order by rand()),
',',
greatest(3-r_counts.cnt,0)) as reviewers
from users u
join users u_rev on u.id != u_rev.id
left join (
select u.id, count(r.id) as cnt
from users u
left join reviews r on u.id = r.id
group by u.id
) r_counts on r_counts.id = u.id
left join (
select u.id, count(r.id) as cnt
from users u
left join reviews r on u.id = r.reviewer
group by u.id, r.reviewer
) as did_review_counts
on did_review_counts.id = u_rev.id
where u.id = 11
and did_review_counts.cnt < 3
group by u.id;
如果你需要另一种结果,谷歌“每组mysql顶部n”,并查看那里的一些解决方案。
注意:以上3就是您的评论号码目标。编辑:现在需要一次只运行1个。然后在每次审核完成后重新运行。