我有一个问题说明,我必须根据他们每月考试的分数来获取每个月(从8月到11月)的前50名唯一学生。唯一的条件是,最终结果必须具有所有唯一名称,总共200个名称。
这是我拥有的数据库结构。
MariaDB [school]> show tables;
+------------------+
| Tables_in_school |
+------------------+
| months |
| overall |
| students |
| scores |
+------------------+
4 rows in set (0.00 sec)
MariaDB [school]> desc students;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.17 sec)
MariaDB [school]> desc scores;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| month_id | int(4) | NO | | NULL | |
| student_id | int(4) | NO | | NULL | |
| score | varchar(255) | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
4 rows in set (0.02 sec)
MariaDB [school]> desc months;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.02 sec)
为了解决这个问题,我提供了一个解决方案,我将选择8月份的前50名学生,然后选择9月的前50名的学生,而不是9月的前50名,依此类推。这是我想出的数据库查询
SELECT student_id FROM scores WHERE month_id = '3' and student_id NOT IN
(SELECT id FROM (SELECT student_id FROM scores WHERE month_id = '2' and student_id NOT IN
(SELECT id FROM (SELECT id FROM scores WHERE month_id = '1' ORDER by scores.id LIMIT 50) august)
ORDER BY scores.id limit 50) september)
ORDER BY scores.id LIMIT 50
显然,我没有得到正确的结果。另外,在最终输出中,我需要从8月到11月的每个月中唯一的前50名,这意味着总共有200名学生名单。但是我真的很困惑如何实现这一目标。请在这里帮助我。
编辑:我在
score
表中添加了scores
列。似乎我没有很好地解释我的问题,因此,我举一个例子。
例:
考虑一下这实际上是数据库的外观。我想要每个月的前三名独特学生,但结果还必须有独特学生。
因此,十月份的前三名学生不应位于九月份的前三名学生中。从9月开始的前3名学生不应在从8月开始的前3名学生中。
MariaDB [deepracer]> select * from scores limit 15;
+----+----------+------------+-------+
| id | month_id | student_id | score |
+----+----------+------------+-------+
| 1 | 1 | 1 | 8.2 |
| 2 | 1 | 6 | 8.3 |
| 3 | 1 | 7 | 8.8 |
| 4 | 1 | 2 | 9.3 |
| 5 | 1 | 4 | 9.4 |
| 6 | 2 | 1 | 8.4 |
| 7 | 2 | 4 | 8.5 |
| 8 | 2 | 6 | 9.4 |
| 9 | 2 | 5 | 9.7 |
| 10 | 2 | 8 | 9.9 |
| 11 | 3 | 3 | 8.1 |
| 12 | 3 | 4 | 8.2 |
| 13 | 3 | 1 | 9.1 |
| 14 | 3 | 2 | 9.3 |
| 15 | 3 | 9 | 9.4 |
+----+----------+------------+-------+
15 rows in set (0.00 sec)
MariaDB [deepracer]> select * from months;
+----+-----------+
| id | name |
+----+-----------+
| 1 | august |
| 2 | september |
| 3 | october |
+----+-----------+
3 rows in set (0.00 sec)
MariaDB [deepracer]> select * from students limit 15;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
| 5 | E |
| 6 | F |
| 7 | G |
| 8 | H |
| 9 | I |
| 10 | J |
+----+------+
10 rows in set (0.00 sec)
因此,最终的最终输出应如下所示:
+------+-----------+-------+
| name | month | score |
+------+-----------+-------+
| A | august | 8.2 |
| F | august | 8.3 |
| G | august | 8.8 |
| D | september | 8.5 |
| E | september | 9.7 |
| H | september | 9.9 |
| C | october | 8.1 |
| B | october | 9.3 |
| I | october | 9.4 |
+------+-----------+-------+
我希望这一点足够清楚,以了解问题是什么,解决方案应该是什么。请让我知道是否还有任何混乱。
最佳答案
首先,将您的表格“总体”删除。然后将新列“得分”添加到表“得分”中。
实际上,表“分数”中的每一行将代表该月学生的分数,例如,该行代表三月(第三个月)的学生1220的分数:
ID MonthID学生ID得分
-------- --------- -----
3 4 1220 57
接下来,由于这看起来像是一个家庭作业问题,因此我不会为您提供SQL,但是您需要做的是:
编写一个查询,将学生与分数联系起来,
将月份限制在八月,
选择不同的学生姓名(即您的查询输出将是姓名列表)
测试此查询并进行修改,直到获得正确的名称列表
在工作之后,通过将其包装在括号中并提供别名,将其转换为“派生表”
然后,在派生表上方添加“选择排名前50位的姓名”,有效地仅选择记录了8月份成绩的50个学生姓名
关于mysql - 获取每月(八月至十一月)的前50条记录,但只有唯一的记录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58575033/