0

我有一个查询如下:

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 个项目。

我如何从 tb1 中选择 2 个不同组中的 2 个随机记录?

4

2 回答 2

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
于 2013-02-05T03:21:43.063 回答
0

我可能误读了您的要求,所以让我澄清一下我认为您要问的内容...来自 tb1 的 2 个不同组中的 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;

预查询(别名为 "AllPossible" )仍然会从两个表中获取您唯一的合格状态 = 1 记录......但是,它首先将它们全部按同一组的顺序排列,然后是随机的,例如

Grp 记录组序列

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 等...have 子句最后声明 I只希望组序列小于 3 的组,因此每组只保留 1 和 2 个,从最终结果集中丢弃所有其余部分。

于 2013-02-05T03:52:58.090 回答