0
点赞
收藏
分享

微信扫一扫

LeetCode刷题之旅【数据库篇-6】 - 中等:178. 分数排名


2019年11月20日

目录

​​题目:分数排名​​

​​解题1​​

​​解题2​​

​​解题3​​

​​解题4​​

题目:分数排名

LeetCode刷题之旅【数据库篇-6】 - 中等:178. 分数排名_javascript

解题1

-- 子查询(分数去重,排名) 语句简洁,可惜列中加子查询性能真的很差
SELECT
Score,
(
SELECT
count(DISTINCT score)
FROM
Scores
WHERE
score >= s.score
) AS Rank
FROM
Scores s
ORDER BY
Score DESC;

LeetCode刷题之旅【数据库篇-6】 - 中等:178. 分数排名_javascript_02

  • 这种方式虽然很简单,但是 在select语句中使用子查询来生成rank,相当于对每一条记录都需要查询一次scores表,查询次数为 (记录条数^2),会很慢,而且在数据量稍大的情况下真的可取吗?

 

解题2

照搬大神的题解进行语句解释,这么简单的方法我怎么就想不到呢?!

select

a.score as Score,

count(DISTINCT b.score) AS Rank # 统计b表符合条件的不重复的分数的数量作为排名

FROM scores a join scores b

where b.score >= a.score # 条件是这个分数不小于我,因为a、b表数据相同,所以排名值最小是1

group by ​​a.id​​ # a表中每个数据都进行排名

order by a.score DESC # 最后按分数(跟排名一样)降序排列

-- 聚合函数,两个相同表的自连接
SELECT
a.Score,
sum(
CASE
WHEN b.Score >= a.Score THEN
1
END
) AS Rank
FROM
Scores a,
(
SELECT DISTINCT
Score
FROM
Scores
) b
GROUP BY
a.id
ORDER BY
a.Score DESC;

LeetCode刷题之旅【数据库篇-6】 - 中等:178. 分数排名_数据_03

 

解题3

  • cast(字段 as signed) 将数据转换为 整型,因为选出来的有双引号,

SELECT Score,
cast((CASE
WHEN @prev = Score THEN @cur
WHEN @prev := Score THEN @cur := @cur + 1
WHEN Score <= 0 THEN @cur := @cur + 1
END) as signed) AS Rank
FROM Scores,
(SELECT @cur := 0, @prev := null) r
ORDER BY
Score DESC;

LeetCode刷题之旅【数据库篇-6】 - 中等:178. 分数排名_数据_04

 

解题4

  • 查询成绩倒叙排列去重 在和主表关联
  • 当前查询结果的行号,

SELECT
d.Score,
c.Rank
FROM
Scores d
LEFT JOIN (
SELECT
@rowNum :=@rowNum + 1 AS 'Rank',
s.Score
FROM
(
SELECT DISTINCT
Score
FROM
Scores
ORDER BY
Score DESC
) s,
(SELECT @rowNum := 0) b -- 行号
) c ON d.Score = c.Score
ORDER BY
c.Rank;

LeetCode刷题之旅【数据库篇-6】 - 中等:178. 分数排名_数据_05

 

 

举报

相关推荐

0 条评论