【问题标题】:How can I randomly select n rows per group a different number of times for each group in MySQL?如何在 MySQL 中为每个组随机选择 n 行不同的次数?
【发布时间】:2021-02-24 08:28:42
【问题描述】:

我基本上有两个表,它们都包含两列 - 人员 ID 和出生年份的列表,如下所示:

ID   birth_year 
1      1981
2      1982
3      1982
4      1983
etc

对于表 1 中的每个人,我需要从表 2 中随机选择出生年份相同的 6 人。

我想我可以在这个查询中使用ORDER BY RAND()LIMIT 6。我的问题是,在表 1 中有许多相同的出生年份,可能是 1987 年出生的 102 人和 1988 年出生的 88 人。我如何编写查询以便它选择 1987 年出生的 6 个随机人 102 次和 88 1988 年的时间?

【问题讨论】:

    标签: mysql loops random


    【解决方案1】:

    我开始学习并开始理解这个 OVER/Partition 概念,并认为它是您正在寻找的。​​p>

    我对“OVER”子句的理解...在您查询的记录中,我希望您根据声明的“PARTITION”组件的定义将它们分成组。因此,根据您的要求,您希望按各自的年份对它们进行分组。

    现在,分区调用中的 ORDER BY 是您应用 RAND() 的地方。因此,在每个 PARTITION(出生年份)内,按 RAND() 对这些记录进行排序。

    所以现在,我们可以使用内置函数 ROW_NUMBER() 来获取记录,因为它们被返回并在组 1、2、3 等中排序......

    通过将其设为内部预查询,您现在可以过滤出最后一行

    select 
          pq.*
       from
          ( select 
                  id,  
                  birth_year, 
                  ROW_NUMBER() OVER(PARTITION BY birth_year order by rand()) finalRow
               from 
                  YourTable
               order by 
                  birth_year ) pq
       where 
          pq.finalRow <= 6
    

    【讨论】:

    • 感谢您的回答!这个查询会给我每个出生年份的六个随机行吗?因为我需要 6*n 随机行,因为表 1 中出生年份相同的人数会有所不同。所以我想我需要一种循环查询,它“扫描”表 1,并且对于表 1 中的每一行,从表 2 中选择 6 个具有相同出生年份的随机行。也许我可以将您编写的查询与这样的循环查询?
    • @millamagia,运行查询...它将为每个出生年份提供 6 个随机条目。无需循环。这就是“OVER(PARTITION)”的用途。这几乎就像为 1979 年 UNION 选择前 6 名,为 1980 年选择前 6 名 UNION 为 1981 年选择前 6 名...
    • 是的,但我需要表 1 中每人 6 个随机条目,而不是每个出生年份。表 1 由 5000 人组成,共有 123 个不同的出生年份,对于每个人,我需要从表 2 中随机选择 6 个出生年份相同的人。因此,我的结果表应该是大约 30 000 人。但是我尝试了您的查询并写了 SELECT table2.ID, table2.birth_year, ROW_NUMBER PARTITION BY table1.ID table1.birth_year ORDER BY RAND(),它给出了正确的行数,但随机化似乎真的不对..同一个人被选中的次数太多以至于它是随机的。
    • @millamagia,然后请编辑您的原始帖子。放置两个表的示例结构并显示一些示例记录(使用空格进行对齐的简单行条目)并显示大约 10-15 行,然后显示您期望得到的示例(显然每个示例数据大小的计数较低,但是足以显示上下文)。您从未表示要反对第二张牌桌。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    相关资源
    最近更新 更多