选择最新的行,然后随机化这些行,然后显示随机化的前 2 行

Posted

技术标签:

【中文标题】选择最新的行,然后随机化这些行,然后显示随机化的前 2 行【英文标题】:Select the latest rows and then randomize those rows and then display the first 2 of the randomized rows 【发布时间】:2020-02-03 18:41:39 【问题描述】:

我有一张桌子叫student_grades

╔════╤═══════╤═══════╤═════════════════════╗
║ id │ name  │ grade │ date_added          ║
╠════╪═══════╪═══════╪═════════════════════╣
║ 1  │ bob   │ 23    │ 2019-10-01 14:25:00 ║
╟────┼───────┼───────┼─────────────────────╢
║ 2  │ james │ 45    │ 2019-10-02 17:31:27 ║
╟────┼───────┼───────┼─────────────────────╢
║ 3  │ mike  │ 42    │ 2019-10-03 18:08:13 ║
╟────┼───────┼───────┼─────────────────────╢
║ 4  │ bob   │ 68    │ 2019-10-04 02:00:00 ║
╟────┼───────┼───────┼─────────────────────╢
║ 5  │ mike  │ 83    │ 2019-10-04 09:28:43 ║
╟────┼───────┼───────┼─────────────────────╢
║ 6  │ bob   │ 23    │ 2019-10-04 11:42:00 ║
╟────┼───────┼───────┼─────────────────────╢
║ 7  │ james │ 86    │ 2019-10-05 12:11:20 ║
╚════╧═══════╧═══════╧═════════════════════╝

首先,我想从表中选择所有名称,但我只想要他们最近的记录。例如。 James 有 2 条记录。一个是id 2,一个是id 7。所以我想要带有id 7 的那个,因为 id 更大。

所以我得到了:

╔════╤═══════╤═══════╤═════════════════════╗
║ id │ name  │ grade │ date_added          ║
╠════╪═══════╪═══════╪═════════════════════╣
║ 5  │ mike  │ 83    │ 2019-10-04 09:28:43 ║
╟────┼───────┼───────┼─────────────────────╢
║ 6  │ bob   │ 23    │ 2019-10-04 11:42:00 ║
╟────┼───────┼───────┼─────────────────────╢
║ 7  │ james │ 86    │ 2019-10-05 12:11:20 ║
╚════╧═══════╧═══════╧═════════════════════╝

.

SELECT *
FROM student_grade 
GROUP BY id
ORDER BY id DESC

现在我想随机化这些行并获取这些随机行的前 2 行

╔════╤═══════╤═══════╤═════════════════════╗
║ id │ name  │ grade │ date_added          ║
╠════╪═══════╪═══════╪═════════════════════╣
║ 7  │ james │ 86    │ 2019-10-05 12:11:20 ║
╟────┼───────┼───────┼─────────────────────╢
║ 5  │ mike  │ 83    │ 2019-10-04 09:28:43 ║
╚════╧═══════╧═══════╧═════════════════════╝

如何随机化这 3 行。我的最终目标是获取每个学生的最新记录。我不在乎他们过去的记录。我只想要他们最近的,然后我想随机化它们。我这样做最有效的方法是什么?

【问题讨论】:

【参考方案1】:

此查询将为您提供所需的结果。它为每个学生找到具有最大 id 值的行,然后对所有这些行进行随机排序并选择 2:

SELECT *
FROM student_grade s
WHERE id = (SELECT MAX(id)
            FROM student_grade
            WHERE name = s.name)
ORDER BY RAND()
LIMIT 2

根据您的表的大小,将其实现为JOIN 可能更有效:

SELECT s1.*
FROM student_grade s1
JOIN (SELECT name, MAX(id) AS id
      FROM student_grade
      GROUP BY name) s2 ON s2.name = s1.name AND s2.id = s1.id
ORDER BY RAND()
LIMIT 2;

Demo on dbfiddle

【讨论】:

这会是最有效的方法吗? 我也看不懂这行WHERE name = s.name这行有什么意义? @Mick 取决于表的大小,JOIN 可能更有效。查看我的编辑。 @Mick WHERE name = s.name 确保子查询返回的 MAX(id) 值与当前输出行中的 name 值相关

以上是关于选择最新的行,然后随机化这些行,然后显示随机化的前 2 行的主要内容,如果未能解决你的问题,请参考以下文章

随机化的奇妙用法

SPSS可以做分层区组随机化的随机分组表吗

随机化初步

用于地图注释随机化的 iOS 自定义图标

VBA - 如何使随机化字符串数组工作?

调用时不播放随机音频列表