【问题标题】:I am using MYSQL for calculating the TOP-N in each subject in a student table.我正在使用 MYSQL 计算学生表中每个科目的 TOP-N。
【发布时间】:2018-11-16 18:19:00
【问题描述】:

我有一个学生表,其中包含 student_id、分数和科目

CREATE TABLE IF NOT EXISTS students 
(student_id INT(3),   subject ,VARCHAR(45),   score INT(3) );

插入的数据是

insert into students values(1,'math',70);
insert into students values(1,'science',71);
insert into students values(1,'history',72);
insert into students values(1,'english',73);
insert into students values(1,'kannada',74);
insert into students values(3,'math',50);
insert into students values(3,'science',51);
insert into students values(3,'history',52);
insert into students values(3,'english',53);
insert into students values(3,'kannada',54);
insert into students values(2,'math',60);
insert into students values(2,'science',61);
insert into students values(2,'history',62);
insert into students values(2,'english',63);
insert into students values(2,'kannada',64);

使用查询后我得到了所需的输出,

select student_id,score,subject
    from
        (select @prev := '', @n:=0) init
    join
        (select @n := if(subject != @prev , 1, @n+1) as n,
                 @prev := subject,
                 student_id,score,subject from students
                 order by
                 subject asc, 
                 score desc
        ) x
        where n<=2
        order by subject, score desc;

我只是不明白这是如何工作的,为什么需要加入?这是子查询吗? from 子句中的语句会在每一行数据上运行吗?有人请给我解释一下。我正在学习 SQL。

注意:我在网上找到了与此类似的查询,我只是根据我的要求对其进行了调整,这不是我的工作。

【问题讨论】:

  • 这与 MySQL 中会话变量的工作方式有关。
  • 好的。明白了。感谢您的回复蒂姆。

标签: mysql groupwise-maximum


【解决方案1】:

只需要连接,以便您可以在查询中初始化变量@prev@n。这需要与您尝试过滤的查询分开完成。您可以改为在查询之前执行此操作,但这会将所有内容放在一个独立的查询中。

SET @prev = '';
SET @n = 0;
SELECT student_id, score, subject
FROM 
    (select @n := if(subject != @prev , 1, @n+1) as n,
             @prev := subject,
             student_id,score,subject from students
             order by
             subject asc, 
             score desc
    ) x
where n<=2
order by subject, score desc;

在这种情况下,使用子查询,以便您可以选择所需的 n &lt;= 2 行。

【讨论】:

  • 感谢您的回复。那么 from 子句中的语句会针对每一行数据运行吗?当我单独运行 from 子句中的语句时,输出为,1 英语 4 153 英语 2 英语 1 73 英语 3 英语 2 63 英语 1 历史 4 152 历史 2 历史 1 72 历史 3 历史 2 62 历史。 @n 的值如何重置为 0 并为每个主题重新启动计数器?
  • SELECT 子句中的语句针对表中的每一行运行。只要主题发生变化,IF() 表达式就会将 @n 重置为 1
  • 所以据我了解, from 子句中的 SELECT 运行并创建一个表,完成后外部 SELECT 选择指定的字段。所以基本上最里面的查询首先运行。
  • 感谢您的时间和耐心巴马尔
猜你喜欢
  • 2022-10-04
  • 2013-03-13
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-07
  • 1970-01-01
相关资源
最近更新 更多