选择最新的行,然后随机化这些行,然后显示随机化的前 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 行的主要内容,如果未能解决你的问题,请参考以下文章