我使用mysql计算学生表中每个主题的top-n

bttbmeg0  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(662)

我有一张学生表,上面有学号、分数和科目

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。
注意:我在网上发现这个查询与此类似,我只是根据自己的要求进行了修改,这不是我的工作。

zy1mlcev

zy1mlcev1#

只需要连接就可以初始化变量 @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 <= 2 您想要的行。

相关问题