mysql使用自定義序列實現row_number功能

水木青楓發表於2021-12-21

看了一些文章,終於知道該怎麼在 mysql 裡面實現 row_number() 排序

話不多說,show you the code:

第一步:建表:

create table grades(
`name` varchar(10),
`subject` varchar(10),
`score` int(10)
)

第二步:寫入資料

insert into grades(name, subject, score)
values('小明', '語文', 85),
('小華', '語文', 89),
('小李', '語文', 91),
('小芳', '語文', 93),
('小明', '數學', 77),
('小華', '數學', 95),
('小李', '數學', 83),
('小芳', '數學', 88),
('小明', '英語', 90),
('小華', '英語', 92),
('小李', '英語', 85),
('小芳', '英語', 88)

資料如下:

第三步:
需求:找出各科目單科第二的同學

首先,先排序:

select name, subject, score 
from grades
order by subject, score desc

資料如下:

然後,每個科目按照分組排序

select (@i:=case when @subject_pre=t1.subject then @i+1 else 1 end) as rn,
t1.*,
(@subject_pre:=subject) 
from (
    select name, subject, score 
    from grades
    order by subject, score desc
) t1, 
(select @i:=0, @subject_pre:='') as t2
group by subject, score
order by subject, score desc

解釋一下:
新增一個比較項 subject_pre, 記錄前一個科目是什麼。
再加上一個自增的序列,實現index+1的功能。
因為資料已經是有序的,如果指向的科目和儲存的前一個科目相同,那麼序號+1,否則的話,序號從1開始重新計算。
這樣就實現了分組排序。

最後,把 rn=2 的資料取出來

select name, subject, score from(
select (@i:=case when @subject_pre=t1.subject then @i+1 else 1 end) as rn,
t1.name,
t1.subject,
t1.score,
(@subject_pre:=subject) 
from (
select name, subject, score 
from grades
order by subject, score desc
) t1, 
(select @i:=0, @subject_pre:='') as t2
group by subject, score
order by subject, score desc
) t
where rn=2

最後結果如下:

這樣就使用mysql實現了row_number()的功能。

在網上找的資料,很多沒寫清楚,這裡特地用一個示例把這個實現講清楚了,希望對你有幫助!

相關文章