mysql8.0查询等级排名可使用窗口函数,那5.7的版本呢?

1、需求:查询用户详情的同时查询用户的排名

在这里插入图片描述

2、首先看下数据库表设计

分为会员用户表member_user和会员等级表member_level,升级的条件是根据经验值升级,表结构如下:

用户表 member_user
CREATE TABLE `member_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `mobile` varchar(11) DEFAULT NULL COMMENT '手机号',
  `status` tinyint(4) NOT NULL COMMENT '状态',
  `nickname` varchar(30) NOT NULL DEFAULT '' COMMENT '用户昵称',
  `avatar` varchar(512) NOT NULL DEFAULT '' COMMENT '头像',
  `sex` tinyint(4) DEFAULT '0' COMMENT '用户性别',
  `level_id` bigint(20) DEFAULT NULL COMMENT '等级编号',
  `experience` int(11) NOT NULL DEFAULT '0' COMMENT '经验',
  `entry_time` datetime DEFAULT NULL COMMENT '入职时间',
  `hobbies` varchar(200) DEFAULT NULL COMMENT '兴趣爱好',
  `brief` varchar(300) DEFAULT NULL COMMENT '简介'
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=304 DEFAULT CHARSET=utf8mb4 COMMENT='会员用户';
会员等级表 member_level
CREATE TABLE `member_level` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `name` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '等级名称',
  `level` int(11) NOT NULL DEFAULT '0' COMMENT '等级',
  `experience` int(11) NOT NULL DEFAULT '0' COMMENT '升级经验',
  `icon` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '等级图标',
  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态'
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='会员等级';

3、根据用户id查询排名

基于等级 level_id和经验 experience 进行排序,sql如下:

3.1、mysql 8.0以上可使用窗口函数
SELECT
    mu.id,
    mu.nickname,
    mu.avatar,
    ml.name AS level_name,
    mu.experience,
    RANK() OVER (ORDER BY ml.level DESC, mu.experience DESC) AS level_rank
FROM
    member_user mu
JOIN
    member_level ml ON mu.level_id = ml.id
WHERE
    mu.id = #{id};

解释:
1、SELECT 子句:选择我们需要的字段,包括会员 ID (member_id)、会员昵称 (member_nickname)、等级名称 (level_name)、经验 (experience),以及计算的排名 (level_rank)。
2、JOIN 语句:通过 level_id 将 member_user 表与 member_level 表连接起来。这样可以获取会员对应的等级名称和等级详细信息。
3、RANK() OVER:这是一个窗口函数,用来根据指定的排序规则对查询结果进行排名。在这里,我们首先按 level (等级) 降序排序,然后按 experience (经验) 降序排序。

以上sql没问题,可我使用的是 mysql 5.7 版本,不支持窗口函数,难道必须升级吗?升级过程出问题了咋整?好的,对症下药,多写两颗代码就搞定。
3.2、mysql 5.7 及更早版本不支持窗口函数。在这种情况下,我们可以使用子查询来实现类似的排名功能
SELECT
    mu.id,
    mu.nickname,
    mu.avatar,
    ml.name AS level_name,
    mu.experience,
    (
        SELECT COUNT(*) + 1
        FROM member_user mu2
                 JOIN member_level ml2 ON mu2.level_id = ml2.id
        WHERE (ml2.level > ml.level) OR (ml2.level = ml.level AND mu2.experience > mu.experience)
    ) AS level_rank
FROM
    member_user mu
JOIN
    member_level ml ON mu.level_id = ml.id
WHERE
    mu.id = #{id};

子查询的工作原理
1、子查询:在主查询的每一行上,子查询都会计算出比当前会员等级高或等级相同但经验更高的会员数量。
2、排名:将子查询的结果加 1 就是当前会员的排名。

总结

根据你的 MySQL 版本选择合适的解决方案。愿你大吉大利,没有bug。如果还有问题,欢迎讨论!

### 功能区别 #### 默认字符集 MySQL 8.0的默认字符集由`latin1`变为`utf8mb4`,而MySQL 5.7仍然使用`latin1`作为默认字符集。这一变化使得MySQL 8.0能够更好地支持多语言和表情符号[^1]。 #### 系统表存储引擎 在MySQL 8.0中,所有的系统表都从`MyISAM`存储引擎迁移到了`InnoDB`存储引擎。这种变化提高了系统的性能和可靠性,因为`InnoDB`支持事务处理和崩溃恢复。而在MySQL 5.7中,系统表仍然使用`MyISAM`存储引擎[^1]。 #### JSON特性增强 MySQL 8.0进一步增强了对JSON数据类型的支持,包括更多的JSON函数和优化的查询性能。MySQL 5.7虽然也引入了JSON数据类型,但其功能和性能不如MySQL 8.0[^1]。 #### 索引和查询优化 MySQL 8.0支持不可见索引(Invisible Indexes)和直方图(Histograms),这些特性可以帮助数据库管理员更灵活地管理和优化查询性能。MySQL 5.7不支持这些特性[^1]。 #### SQL模式 MySQL 8.0的`sql_mode`参数默认值有所变化,去除了`NO_AUTO_CREATE_USER`,并增加了`STRICT_TRANS_TABLES`。这些变化使得SQL模式更加严格,有助于提高数据的一致性和完整性[^1]。 #### 密码策略 MySQL 8.0默认密码策略有所变更,增强了安全性。例如,引入了新的身份验证插件`caching_sha2_password`,取代了旧的`mysql_native_password`插件。MySQL 5.7的密码策略相对较为宽松。 #### 角色管理 MySQL 8.0引入了角色管理功能,允许用户创建和管理角色,并将权限分配给角色,而不是直接分配给用户。这简化了权限管理。MySQL 5.7不支持角色管理[^1]。 #### 窗口函数 MySQL 8.0支持窗口函数,这使得复杂查询的编写变得更加简单和高效。MySQL 5.7不支持窗口函数。 #### 空间函数 MySQL 8.0引入了标准化的空间函数,例如`ST_GeomFromText`函数取代了MySQL 5.7中的`GeomFromText`函数。这一变化使得MySQL 8.0与其他数据库系统更好地兼容[^2]。 #### 存储引擎 MySQL 8.0进一步减少了对`MyISAM`存储引擎的支持,尤其是在系统表中全面采用`InnoDB`。MySQL 5.7虽然也开始逐步减少对`MyISAM`的依赖,但仍然保留了一些`MyISAM`系统表[^1]。 ### 示例代码 以下是一个示例,展示了如何在MySQL 8.0使用`ST_GeomFromText`函数: ```sql SELECT ST_GeomFromText('POINT(1 1)'); ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT刘大华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值