在mysql中以随机顺序从2个表中选择2个不同的记录

时间:2013-02-05 02:58:17

标签: mysql

我的查询如下:

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个随机记录?

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个,从最终结果集中抛弃所有其余部分。