前言 最近项目需要开发一个排行榜功能,根据订单金额进行排名,同金额排名相同,不同则跳过,序列递增。 技术实现 MySQL 通过SQL语句也能实现,不过SQL过于复杂,也不好维护。 SELECT ... WHEN @pre := final_score
最近项目需要开发一个排行榜功能,根据订单金额进行排名,同金额排名相同,不同则跳过,序列递增。
MySQL 通过SQL语句也能实现,不过SQL过于复杂,也不好维护。
SELECT
CASE
WHEN
@pre = final_score THEN
@pic + 0
WHEN @pre := final_score THEN
@pic := @pic + 1 ELSE @pic := @pic + 1
END AS rank,
rr.id registrationRecordId,
rr.final_score AS number,
us.userName,
us.id userId,
us.avatarImageURL headPortrait,
CAST( p.`projectName` AS CHAR CHARSET UTF8 ) AS projectName,
p.thumbnailURL,
p.id projectId
FROM
registration_record rr
INNER JOIN `user` us ON rr.user_id = us.id
INNER JOIN project p ON p.id = rr.project_id,(
SELECT
@pre := NULL,
@pic := 0
) AS init
WHERE
rr.final_score IS NOT NULL
AND rr.competition_id = 41
ORDER BY
rr.final_score DESC
SQL类似这样,光从可读性就能劝退很多同学了。
Redis Redis也能实现排行榜功能,主要通过zset中的分数特性来实现,不过对于我的业务不太适合 SQL+Java代码 通过SQL中的order by将查询的List根据某字段进行排好序,再将此List通过Java代码实现最终排行榜功能(推荐使用)
//伪SQL
select
a.schoolId
a.schoolName,
sum(a.amount)as count
from a
group by a.schoolId
order by count desc
将需要排序的集合通过某字段排好序 Java代码
/**
* 成交金额排名
*
* @param amountRankList
* @return
*/
private static List<AmountRankVO> amountRank(List<AmountRankVO> amountRankList) {
amountRankList.sort((s1, s2) -> -Float.compare(s1.getCount(), s2.getCount()));
int index = 0;
int count = 0;
int tmpSize = 0;
Float lastCount = -1.00f;
List<AmountRankVO> tmpAmountRankList = new ArrayList<>();
for (int i = 0; i < amountRankList.size(); i++) {
AmountRankVO amountRankVO = amountRankList.get(i);
if (Double.compare(lastCount, amountRankVO.getCount()) != 0) {
lastCount = amountRankVO.getCount();
index = index + 1 + count;
count = 0;
}
amountRankVO.setSequence(index);
//相同并列,不同则跳过,序号一次递增
if (tmpSize > 0) {
if (amountRankVO.getCount() < amountRankList.get(tmpSize - 1).getCount()) {
amountRankVO.setSequence(tmpSize + 1);
index = tmpSize + 1;
}
}
tmpAmountRankList.add(amountRankVO);
tmpSize = tmpAmountRankList.size();
}
return tmpAmountRankList;
}
如果想实现同金额相同排名,不出现序列自增,只需注释下面代码:
//相同并列,不同则跳过,序号一次递增
if (tmpSize > 0) {
if (amountRankVO.getCount() < amountRankList.get(tmpSize - 1).getCount()) {
amountRankVO.setSequence(tmpSize + 1);
index = tmpSize + 1;
}
}
最后我们看一下具体实现的效果,类似功能比如成绩排名,销量排名等都能适用
本站为非盈利网站,如果您喜欢这篇文章,欢迎支持我们继续运营!
本站主要用于日常笔记的记录和生活日志。本站不保证所有内容信息可靠!(大多数文章属于搬运!)如有版权问题,请联系我立即删除:“abcdsjx@126.com”。
QQ: 1164453243
邮箱: abcdsjx@126.com