sql實現TOPN


轉載鑫語大數據的  微信存不了收藏夾  復制過來的  侵權立刪

 

CREATE TABLE `test1` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(20) DEFAULT NULL,

  `course` varchar(20) DEFAULT NULL,

  `score` int(11) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

 

insert into test1(name,course,score)

values

('張三','語文',80),

('李四','語文',90),

('王五','語文',93),

('張三','數學',77),

('李四','數學',68),

('王五','數學',99),

('張三','英語',90),

('李四','英語',50),

('王五','英語',89);

 

select * from test1;

 

 

 

Top 1

查詢每門課程分數最高的學生以及成績

1、使用自連接【推薦】

select a.name,a.course,a.score from test1 a

join (select course,max(score) score from test1 group by course) b

on a.course=b.course and a.score=b.score;

 

 

 

 

 

2、使用相關子查詢

select `name`,course,score from test1 a

where score=(select max(score) from test1 where a.course=test1.course);

 

 

 

select `name`,course,score from test1 a

where not exists

(select 1 from test1 where a.course=test1.course and a.score < test1.score);

 

 

 

Top N

N>=1

查詢每門課程前兩名的學生以及成績

1、使用union all

如果結果集比較小,可以用程序查詢單個分組結果后拼湊,也可以使用union all

(select name,course,score from test1 where course='語文' order by score desc limit 2) union all

(select name,course,score from test1 where course='數學' order by score desc limit 2) union all

(select name,course,score from test1 where course='英語' order by score desc limit 2);

 

 

 

2、自身左連接

select a.name,a.course,a.score

from test1 a left join test1 b on a.course=b.course and a.score<b.score

group by a.name,a.course,a.score

having count(b.id)<2

order by a.course,a.score desc;

 

 

 

3、相關子查詢

select * from test1 a

where 2>(select count(*) from test1 where course=a.course and score>a.score)

order by a.course,a.score desc;

 

 

4、使用用戶變量

set @num := 0, @course := '';

select name, course, score

from (

select name, course, score,

@num := if(@course = course, @num + 1, 1) as row_number,

@course := course as dummy

from test1 order by course, score desc) as x

where x.row_number <= 2;

 

 

 

備注:

如果是oracel

SELECT * FROM (SELECT ROW_NUMBER() OVER(PARTITION BY x ORDER BY y DESC)

rn,test1.* FROM test1)        

WHERE rn = 1 ;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM