【问题标题】:Select 2, distinct records from 2 tables, in random order, in mysql选择2,从2个表中的不同记录,以随机顺序,在mysql中
【发布时间】:2013-02-05 02:58:17
【问题描述】:

我有一个查询如下:

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

【问题讨论】:

    标签: mysql


    【解决方案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
    

    【讨论】:

      【解决方案2】:

      我可能误读了你的要求,所以让我澄清一下我认为你在问什么...... 来自 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”)仍会从两个表中获取您唯一的合格 status=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 个,而从最终结果集中排除所有其余部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多