我的查询如下:
SELECT tb1.id, tb2.id
FROM tb1
JOIN tb2 ON tb1.group = tb2.id
WHERE
tb1.status = 1 AND tb2.status = 1
GROUP BY tb1.group
ORDER BY RAND( )
LIMIT 2
两个表都很小(1000行以下),所以ORDER BY RAND()很好。
对于tb2中的每条记录,tb1中有10条记录(由tb2.id = tb1.group链接)。我想选择2个不同的组,每组有一个tb1的随机记录。
拥有GROUP BY子句总是从tb1中选择组中的第一条记录。删除GROUP BY子句,它会随机选择一个随机的子句......但它可以偶尔在同一组中选择2个项目。
如何在2个不同的组中从tb1中选择2个随机记录?
答案 0 :(得分:1)
不知何故,这似乎比我想象的要复杂,但我认为它符合你的要求:
select tb2.*,
(select tb1.id from tb1 where tb1.group = tb2.id and tb1.status = 1 order by rand() limit 1)
from tb2
where tb2.status = 1 and
exists (select 1 from tb1 where tb1.status = 1 and tb1.group = tb2.id)
group by tb2.id
order by rand()
limit 2
答案 1 :(得分:0)
我可能误读了你的要求,所以让我澄清一下你在想什么...... 2个不同组中来自tb1的2个随机记录...对于每个tb2记录,您需要来自tb1表的两个随机记录。因此,如果tb2有100条记录,你需要200个结果集... 2个用于组#1,2个用于组#2,2个用于组#3等。
如果是这样,我只会打包你的查询并利用MySQL变量并为每个组设置一个计数器并应用一个HAVING子句......
select
AllPossible.group,
@lastSeq := if( AllPossible.group = @lastGroup, @lastSeq +1, 1 ) as GroupSeq,
@lastGroup = AllPossible.group
from
( SELECT
tb1.id,
tb2.id
FROM
tb1
JOIN tb2
ON tb1.group = tb2.id
WHERE
tb1.status = 1
AND tb2.status = 1
ORDER BY
tb1.group,
RAND( ) ) AllPossible,
( select @lastGroup := 0,
@lastSeq := 0 ) sqlvars
having
GroupSeq < 3;
prequery(别名“AllPossible”)仍然获得你的唯一合格状态=从两个表加入的1条记录...但是,它首先将它们全部按顺序排列,然后是随机的,例如
Grp Record Group Seq
1 19 1 (keep)
1 95 2 (keep)
1 3 3 (throw away)
1 28 4 (throw away)
2 34 1 (keep)
2 14 2 (keep)
2 89 3 (throw away)
2 41 4 (throw away)
3 9 1 (keep)
3 25 2 (keep)
3 42 3 (throw away)
3 76 4 (throw away)
由此,它依次分配“组序列”。由于首先应用RAND()并以随机顺序返回,它只标记记录1,2,3,4,(下一组) - 1,2,3,4等......有条款最后说明我只想要那些组序列小于3的人,因此只保留1&amp;每组2个,从最终结果集中抛弃所有其余部分。