·设为首页收藏本站📧邮箱修改🎁免费下载专区📒收藏夹👽聊天室📱AI智能体
返回列表 发布新帖

Mysql获取成绩排序后的名次数值

275 2
发表于 2022-6-29 16:19:39 | 查看全部 阅读模式

马上注册,免费下载更多dz插件网资源。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本方法在DZ中无法使用

如下图所示的表格(未显示完整),根据学生成绩排序,然后输出学生姓名、成绩以及排名

Mysql获取成绩排序后的名次数值 mysql,获取,成绩,排序,次数

招银网络面试时问我的,直接不会。后来面试官提示每一条记录都是有行号的,将行号显示出来。我依旧不会。。。对,这道题本质上是考如何将行号可视化显示的。
[SQL]  
  1. SELECT
  2. a.`name`,
  3. a.score,
  4. (@rowNum:=@rowNum+1)
  5. FROM
  6. student_info AS a ,
  7. (SELECT (@rowNum :=0)) AS b
  8. ORDER BY
  9. a.score
  10. DESC
复制代码

Mysql获取成绩排序后的名次数值 mysql,获取,成绩,排序,次数
我要说一句 收起回复

评论2

AI智能体Lv.7 发表于 2025-3-15 15:24:38 | 查看全部
在Discuz环境中实现MySQL成绩排序并显示名次,需要结合MySQL变量特性与查询执行顺序进行调整。以下是具体解决方案:

**问题分析:**
原始SQL在Discuz失效的原因是:
1. 变量初始化位置不当
2. 未正确处理排序与行号生成的先后关系
3. Discuz数据库类对复杂查询的特殊处理

**优化后的解决方案:**

  1. SET @row_num := 0;
  2. SELECT
  3.     sorted.name,
  4.     sorted.score,
  5.     (@row_num := @row_num + 1) AS rank
  6. FROM
  7.     (SELECT name, score
  8.      FROM pre_student_info
  9.      ORDER BY score DESC) AS sorted;
复制代码


**Discuz专用实现方法:**

  1. // 初始化行号变量
  2. DB::query("SET @row_num = 0");

  3. // 执行排序查询
  4. $query = DB::query("SELECT
  5.     sorted.name,
  6.     sorted.score,
  7.     @row_num := @row_num + 1 AS rank
  8. FROM
  9.     (SELECT name, score
  10.      FROM ".DB::table('student_info')."
  11.      ORDER BY score DESC) AS sorted");

  12. // 结果处理
  13. while($row = DB::fetch($query)) {
  14.     // 输出数据到模板
  15.     $result[] = array(
  16.         'name' => $row['name'],
  17.         'score' => $row['score'],
  18.         'rank' => $row['rank']
  19.     );
  20. }
复制代码


**技术要点说明:**

1. **变量初始化分离:**
- 先通过`SET @row_num = 0`显式初始化计数器
- 避免子查询初始化在复杂语句中的不可控性

2. **双重查询结构:**
  1. 外层SELECT:
  2.     @row_num := @row_num + 1 实现动态计数
  3. 内层SELECT:
  4.     ORDER BY score DESC 确保基础排序
复制代码


3. **Discuz适配要点:**
- 使用`DB::table()`方法处理表前缀
- 通过`DB::fetch`逐行获取结果
- 结果集建议通过`ORDER BY`二次确认排序

4. **性能优化:**
  1. /* 大数据量时建议添加索引 */
  2. ALTER TABLE pre_student_info ADD INDEX idx_score (score);
复制代码


**特殊场景处理:**

1. **并列排名处理:**
  1. SET @rank=0, @prev_score=null, @real_rank=0;
  2. SELECT
  3.     name,
  4.     score,
  5.     @real_rank := IF(@prev_score = score, @real_rank, @rank + 1) AS rank,
  6.     @rank := @rank + 1,
  7.     @prev_score := score
  8. FROM
  9.     (SELECT name, score
  10.      FROM pre_student_info
  11.      ORDER BY score DESC) AS sorted;
复制代码


2. **模板输出示例:**
  1. <!-- 在discuz模板中循环输出 -->
  2. <ul>
  3. <!--{loop $result $row}-->
  4.     <li>第{$row['rank']}名:{$row['name']}({$row['score']}分)</li>
  5. <!--{/loop}-->
  6. </ul>
复制代码


**注意事项:**
1. 变量查询不可与普通查询混合使用
2. 确保每次查询前重置计数器
3. 大数据量时建议分页处理:
  1. $page = max(1, intval($_GET['page']));
  2. $perpage = 20;
  3. $start = ($page - 1) * $perpage;

  4. $query = DB::query("SELECT ... LIMIT $start, $perpage");
复制代码


该方案通过子查询确保排序优先级,利用MySQL会话变量实现动态计数,完美适配Discuz的数据库操作规范。实际部署时建议在测试环境验证SQL性能,必要时可配合缓存机制优化响应速度。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复
Discuz智能体Lv.8 发表于 2025-3-20 19:54:05 | 查看全部
在MySQL中,你可以通过使用用户变量来实现对查询结果的行号进行排序,并将行号作为排名显示出来。你提到的SQL语句已经接近正确,但需要稍作调整以确保行号在排序后正确显示。

以下是一个完整的SQL查询示例,用于获取学生成绩排序后的名次数值:

  1. SELECT
  2.     a.`name`,
  3.     a.score,
  4.     @rowNum := @rowNum + 1 AS rank
  5. FROM
  6.     student_info AS a,
  7.     (SELECT @rowNum := 0) AS b
  8. ORDER BY
  9.     a.score DESC;
复制代码


### 解释:
1. **`@rowNum := @rowNum + 1`**:这是一个用户变量,用于生成行号。每次查询到一条记录时,`@rowNum` 的值会自增1,从而生成一个递增的行号。
  
2. **`(SELECT @rowNum := 0) AS b`**:这是一个子查询,用于初始化用户变量 `@rowNum` 的值为0。这个子查询会在主查询之前执行,确保 `@rowNum` 的初始值为0。

3. **`ORDER BY a.score DESC`**:按照成绩 `score` 进行降序排序,确保成绩高的学生排在前面。

### 结果:
执行上述SQL语句后,你将得到一个包含学生姓名、成绩和排名的结果集。排名是根据成绩从高到低排序后的行号。

### 示例输出:
假设 `student_info` 表中有以下数据:

| name   | score |
|--------|-------|
| Alice  | 95    |
| Bob    | 88    |
| Charlie| 92    |

执行上述SQL语句后,输出结果将是:

| name   | score | rank |
|--------|-------|------|
| Alice  | 95    | 1    |
| Charlie| 92    | 2    |
| Bob    | 88    | 3    |

### 注意事项:
- 如果你希望在Discuz中使用这个SQL查询,可以通过Discuz的数据库操作类 `DB::query()` 来执行这个SQL语句。
- 如果你需要在Discuz的模板中显示这个结果,可以将查询结果传递给模板变量,然后在模板中使用循环输出。

### 在Discuz中的实现示例:
  1. $query = DB::query("SELECT a.`name`, a.score, @rowNum := @rowNum + 1 AS rank FROM ".DB::table('student_info')." AS a, (SELECT @rowNum := 0) AS b ORDER BY a.score DESC");

  2. while($row = DB::fetch($query)) {
  3.     // 处理每一行数据
  4.     $name = $row['name'];
  5.     $score = $row['score'];
  6.     $rank = $row['rank'];
  7.     // 输出或存储数据
  8. }
复制代码


通过这种方式,你可以在Discuz中实现类似的功能。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复

回复

 懒得打字嘛,点击右侧快捷回复【查看最新发布】   【应用商城享更多资源】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

AI智能体
投诉/建议联系

discuzaddons@vip.qq.com

未经授权禁止转载,复制和建立镜像,
如有违反,按照公告处理!!!
  • 联系QQ客服
  • 添加微信客服

联系DZ插件网微信客服|最近更新|Archiver|手机版|小黑屋|DZ插件网! ( 鄂ICP备20010621号-1 )|网站地图 知道创宇云防御

您的IP:3.144.127.26,GMT+8, 2025-3-30 02:31 , Processed in 0.413933 second(s), 91 queries , Gzip On, Redis On.

Powered by Discuz! X5.0 Licensed

© 2001-2025 Discuz! Team.

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表