选择最新的行并且恰好 2 行具有一个条件和 2 行具有不同的条件
Posted
技术标签:
【中文标题】选择最新的行并且恰好 2 行具有一个条件和 2 行具有不同的条件【英文标题】:Select the latest rows and exactly 2 rows with one condition and 2 with a different condition 【发布时间】:2020-02-03 19:18:02 【问题描述】:我有一张桌子叫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 │ 93 │ 2019-10-04 11:42:00 ║
╟────┼───────┼───────┼─────────────────────╢
║ 7 │ james │ 98 │ 2019-10-05 14:51:20 ║
╟────┼───────┼───────┼─────────────────────╢
║ 8 │ steph │ 72 │ 2019-10-05 15:31:20 ║
╟────┼───────┼───────┼─────────────────────╢
║ 9 │ john │ 78 │ 2019-10-05 16:33:20 ║
╟────┼───────┼───────┼─────────────────────╢
║ 10 │ john │ 74 │ 2019-10-05 17:42:23 ║
╟────┼───────┼───────┼─────────────────────╢
║ 10 │ nick │ 92 │ 2019-10-05 17:59:12 ║
╚════╧═══════╧═══════╧═════════════════════╝
我使用此语句获取学生的最新记录。例如。 James
有 2 条记录。一个是id 2
,一个是id 7
。所以我想要带有id 7
的那个,因为 id 更大。
然后我随机化这些行并返回我
╔════╤═══════╤═══════╤═════════════════════╗
║ id │ name │ grade │ date_added ║
╠════╪═══════╪═══════╪═════════════════════╣
║ 7 │ james │ 86 │ 2019-10-05 12:11:20 ║
╟────┼───────┼───────┼─────────────────────╢
║ 5 │ mike │ 83 │ 2019-10-04 09:28:43 ║
╚════╧═══════╧═══════╧═════════════════════╝
声明:
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;
我的问题是,2个分数在70-80之间(随机选择)和2个分数在90-99之间(随机选择)的学生,我如何选择最新记录。 p>
SELECT s1.*
FROM student_grade s1
JOIN (SELECT name, MAX(id) AS id
FROM student_grade
WHERE (grade >= 70 and grade <= 80) or (grade >= 90 and grade <= 99)
GROUP BY name) s2 ON s2.name = s1.name AND s2.id = s1.id
ORDER BY RAND()
LIMIT 4;
但如果我按照上面的说法,它可能给我 3 个得分为 70-80 的学生和 1 个得分为 90-99 的学生。我想要正好 2 个 70-80 岁的学生(随机选择)和 90-99 岁的正好 2 个(随机选择)。我该怎么做?
【问题讨论】:
【参考方案1】:我的问题是,我如何选择 2 个分数在 70 到 80 之间的学生(随机选择)和 2 个分数在 90 到 99 之间的学生(随机选择)的最新记录。
在 mysql 8+ 中,最简单的方法是使用行号:
select sg.*
from (select sg.*
row_number() over (partition by (case when grade between 70 and 80 then 1 when grade between 90 and 99 then 2 else 3 end)
order by rand()
) as seqnum
from student_grades sg
where grade between 70 and 80 or grade between 90 and 99
) sg
where seqnum <= 2;
【讨论】:
【参考方案2】:您可以将两个现有查询UNION ALL
一起获得您想要的结果:
(SELECT s1.*
FROM student_grade s1
JOIN (SELECT name, MAX(id) AS id
FROM student_grade
WHERE grade BETWEEN 70 AND 80
GROUP BY name) s2 ON s2.name = s1.name AND s2.id = s1.id
ORDER BY RAND()
LIMIT 2)
UNION ALL
(SELECT s1.*
FROM student_grade s1
JOIN (SELECT name, MAX(id) AS id
FROM student_grade
WHERE grade BETWEEN 90 AND 99
GROUP BY name) s2 ON s2.name = s1.name AND s2.id = s1.id
ORDER BY RAND()
LIMIT 2)
Demo on dbfiddle
我们可以使用UNION ALL
,因为我们知道不会有任何重复,因为等级范围不同。
【讨论】:
谢谢。如果我想再次随机化整个结果怎么办。所以我从70-80
范围中选择2,从90-99
范围中选择2。在我得到这 4 个结果之后。我怎样才能随机化这 4 个的顺序。
@Mick 理论上UNION
的输出是不确定的,但要确保它是随机的,您可以将ORDER BY RAND()
添加到查询的末尾以上是关于选择最新的行并且恰好 2 行具有一个条件和 2 行具有不同的条件的主要内容,如果未能解决你的问题,请参考以下文章