【问题标题】:Select random 4 rows using inner join使用内连接选择随机 4 行
【发布时间】:2017-07-29 19:47:30
【问题描述】:

我的桌子是这样的:

test_ques
------------------------------
id | ques | skill_id
1  | xyz  | 1
2  | xyz  | 1
3  | xyz  | 1
4  | xyz  | 1
5  | xyz  | 1
6  | xyz  | 2
7  | xyz  | 2
8  | xyz  | 2
9  | xyz  | 2
10 | xyz  | 2
11 | xyz  | 2
12 | xyz  | 3
13 | xyz  | 3
14 | xyz  | 3
15 | xyz  | 3
16 | xyz  | 3
17 | xyz  | 3

skills
------------
id | score
1  | 15
2  | 20
3  | 25

我想从表 test_ques 中随机选择每个 Skill_id 的 4 行

我想知道如何执行上述操作并使用内部连接从技能表中获取分数。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    您可以使用由RAND() 排序的GROUP_CONCAT() 将每个skill_id 的ID 存储在一个字符串中。然后使用 FIND_IN_SET() 将子查询与选择前 4 个的表连接起来。

    select q.*
    from (
      select skill_id, group_concat(id order by rand()) as ids
      from test_ques
      group by skill_id
    ) sub
    join test_ques q
      on  q.skill_id = sub.skill_id
      and find_in_set(q.id, sub.ids) <= 4
    

    http://sqlfiddle.com/#!9/55730/6

    【讨论】:

    • 完美运行,但是这个查询可以更简单吗?
    • @ιηςπεδιδιεζαυπαυ 我不知道更简单的方法(在一个查询中)。如果有人找到了,我想看看。
    【解决方案2】:

    在 MySQL 中,最简单的方法是枚举每个 skill_id 的行,然后选择四个:

    select t.*
    from (select t.*,
                 (@rn := if(@s = skill_id, @rn + 1,
                            if(@s := skill_id, 1, 1)
                           )
                 ) as rn
          from test_ques t cross join
               (select @s := -1, @rn := 0) params
          order by skill_id, rand()
         ) t
    where rn <= 4;
    

    【讨论】:

    • 此查询每次都随机返回相同的行。
    • 您可以为随机数生成器播种,但它不应返回相同的行。
    • @ιηςπεδιδιεζαυπαυ。 . .这是一个替代方案。这使您可以从行中获取所有信息,而不仅仅是 id。如果您重新连接到另一个表,这也应该更快,因为它允许join 使用索引。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 2021-01-09
    • 2011-09-26
    • 1970-01-01
    • 2014-06-12
    • 2020-06-29
    • 2016-02-20
    相关资源
    最近更新 更多