我一直相信, 人是能预测未来的, 这应该是前几年看弗洛伊德, 荣格的一些心理学书, 给我的一些感受, 有个片段是关于做梦的, 一个人梦见子弹穿过他自己的头颅, 结果不久, 他就去世了. 这个片段当时给了我很多奇思妙想, 关于人类的潜意识, 也许未来就在潜意识中, 但生活中可能无法察觉到这一点.

开头有点偏了, 也是为了引出一个今天的话题, 我上午有一个面谈, 我冥冥中就感觉会被问到 sql 排序问题, 之前也写过, 做了笔记, 但临场还是给忘了, 然后是一些 GBDT, XGBOOST, 决策树, 随机森林这些话题, 我也是准备没那么充分, 虽说都这些的数学原理我都是推导过的.. 哎...最后也没能再争取一下, 有点难受, 即便如此, 还是给推荐了我的笔记, 希望能遇见伯乐吧, 笔记是真诚的.

Rank 排序实现

排名这块, 我虽然近几个月写了几千行 SQL 了, rank 其实没有写过, Oracle 有这种 rank () 之类的窗口函数, 但 Mysql 是没有的, 要自己来实现一把.

测试数据, 还是用之前联系的 cj.score 表来展示, 数据如下:

mysql> select * from cj.score;

+------+------+-------+

| s_id | c_id | score |

+------+------+-------+

| 0001 | 0001 | 80 |

| 0001 | 0002 | 90 |

| 0001 | 0003 | 99 |

| 0002 | 0002 | 60 |

| 0002 | 0003 | 80 |

| 0003 | 0001 | 80 |

| 0003 | 0002 | 80 |

| 0003 | 0003 | 80 |

+------+------+-------+

8 rows in set (0.00 sec)

思路

首先, 定义两个变量, 就叫 @rank, 和 @pre

@rank 用于记录排名值, 初始值为 0

@pre 用于上一条记录的分数 score 值, 初始值为 null.

给自定义变量赋值有2种方法,一种是用set,另一种使用select ; 而且赋值推荐使用 := 这种方式.

select @rank := 0, @pre := null

然后, 对每条数据进行判断.

@rank := if (@pre=score, @rank, @rank+1) as rank,

@pre := score

算法:

大前提: 先要对数据集中, 该排序字段进行降序

for 遍历第一条记录的时候, @rank 值为0, @pre 值为 null:

if @pre = score:

# 排名不变

@rank + 0

else:

#

@rank + 1

当遍历到第二条记录, 此时 @rank = 1, @pre 为上条记录的score值.

if 当前的 score 值 = 上一条的 score 值, 就排名不变嘛, 还是 @rank;

不等于就 @rank + 1

... 这样就保证相同分数的排名相等, 不同排名会使 rank 增加, 且不会出现间隔

实现

-- step1: 定义变量, 并对数据集按 score 降序

-- 相当于把主表, 添加两个字段

select

a.* ,

b.*

from cj.score as a, (select @rank:=0, @pre:=null) as b

order by a.score desc

+------+------+-------+----------+------------+

| s_id | c_id | score | @rank:=0 | @pre:=null |

+------+------+-------+----------+------------+

| 0001 | 0003 | 99 | 0 | NULL |

| 0001 | 0002 | 90 | 0 | NULL |

| 0001 | 0001 | 80 | 0 | NULL |

| 0002 | 0003 | 80 | 0 | NULL |

| 0003 | 0001 | 80 | 0 | NULL |

| 0003 | 0002 | 80 | 0 | NULL |

| 0003 | 0003 | 80 | 0 | NULL |

| 0002 | 0002 | 60 | 0 | NULL |

+------+------+-------+----------+------------+

8 rows in set (0.00 sec)

select

-- 动态来计算 rank 值

a.score ,

@rank:= if(@pre=a.score, @rank+0, @rank+1) as my_rank ,

@pre:=score

-- 0: 给主表添加上两个字段

from cj.score as a, (select @rank:=0, @pre:=null) as b

order by a.score desc

+-------+---------+-------------+

| score | my_rank | @pre:=score |

+-------+---------+-------------+

| 99 | 1 | 99 |

| 90 | 2 | 90 |

| 80 | 3 | 80 |

| 80 | 3 | 80 |

| 80 | 3 | 80 |

| 80 | 3 | 80 |

| 80 | 3 | 80 |

| 60 | 4 | 60 |

+-------+---------+-------------+

8 rows in set (0.00 sec)

搞定, 这样就已经排序出来了. 最后还是来一个完整版的, 把其他字段补全, 不需要显示的 @pre 字段给干掉.

select

c.s_id,

c.c_id,

c.score,

c.my_rank as score_rank

from (

select

a.s_id,

a.c_id,

a.score,

@rank := if(@pre=score, @rank + 0, @rank + 1) as my_rank,

@pre := score

from cj.score as a, (select @rank:=0, @pre=null) as b

order by a.score desc

) as c

+------+------+-------+------------+

| s_id | c_id | score | score_rank |

+------+------+-------+------------+

| 0001 | 0003 | 99 | 1 |

| 0001 | 0002 | 90 | 2 |

| 0001 | 0001 | 80 | 3 |

| 0002 | 0003 | 80 | 3 |

| 0003 | 0001 | 80 | 3 |

| 0003 | 0002 | 80 | 3 |

| 0003 | 0003 | 80 | 3 |

| 0002 | 0002 | 60 | 4 |

+------+------+-------+------------+

8 rows in set (0.00 sec)

关于 SQL != 的问题

我是前段时间, 无意中发现的, 在通常的认知中, "等于" 和 "不等于" 二者应该是 矛盾关系, 是对立统一的, 但无意间发现 Null 的时候, 并非如此.

先来正常的. 我用一个常用的 超市数据集做演示, 有一个字段 category 产品的分类, 先分别统计它的分类值数量:

select

category,

count(category) as cnt

from cj.super_market

group by category

+--------------+------+

| category | cnt |

+--------------+------+

| 办公用品 | 5687 |

| 家具 | 2244 |

| 技术 | 2028 |

+--------------+------+

3 rows in set (0.01 sec)

mysql> select 5687 + 2244 + 2028;

+--------------------+

| 5687 + 2244 + 2028 |

+--------------------+

| 9959 |

+--------------------+

1 row in set (0.00 sec)

可以看到总数: 办公用品 + 家具 + 技术 = 5687 + 2244 + 2028 = 9959

先进行过滤, 将家具排除掉, 理论上, 总数应该是 : 5687 + 2028 = 7715

select count(id) from cj.super_market where category != '家具';

7715

哦.. . 是对的, 我好像之前自己写 SB 了...呀, 心态崩了, 之前以为的 bug 是把 2028 写成了2208 导致错误..

想说的是, 当值有 null 的时候, 要单独来考虑...

我傻了, 弄混淆了 count(*) 是会计算所有的行数, 包括 null 的, 而 count(col) 会忽略 null 的行, 导致总数对不上, 此刻我对自己有些无语...

嗯不举例了, 我现在需要冷静一下, 好好回溯下这个问题.

mysql不支持rank()_Mysql 实现 rank 和 != 问题相关推荐

  1. mysql 不支持分区_MySQL分区表的局限和限制

    禁止构建 分区表达式不支持以下几种构建: 存储过程,存储函数,UDFS或者插件 声明变量或者用户变量 算术和逻辑运算符 分区表达式支持+,-,*算术运算,但是不支持DIV和/运算(还存在,可以查看Bu ...

  2. mysql 不支持表情符号_mysql中插入emoji表情失败的原因与解决

    失败场景 用户昵称中存在emoji表情,调用jdbc往mysql数据库插入的时候抛出异常 java.sql.SQLException: Incorrect string value: '\xF0\x9 ...

  3. mysql替换sql中rank函数_MySQL sql Rank()函数实现

    一字符串类 Ø  Concat函数:连接字符串 Ø  Instr函数:返回字符串在某一个字段的内容中的位置, 没有找到字符串返回0,否则返回位置(从1开始) Ø  字符串大小写转换[upper().u ...

  4. mysql over rank_mysql实现Oracle 的rank() over()函数

    之前要查询排序且有排名,如果是oracle的话有rank() over()函数,但是mysql没有这样的函数,只能自己试着用变量实现 表结构: SELECT id, score , @rank := ...

  5. mysql 编程处理数据类型_Mysql支持的数据类型(总结)

    一.数值类型 Mysql支持所有标准SQL中的数值类型,其中包括严格数据类型(INTEGER,SMALLINT,DECIMAL,NUMBERIC),以及近似数值数据类型(FLOAT,REAL,DOUB ...

  6. mysql数据类型支持比较运_Mysql支持的数据类型(总结)

    一.数值类型 Mysql支持所有标准SQL中的数值类型,其中包括严格数据类型(INTEGER,SMALLINT,DECIMAL,NUMBERIC),以及近似数值数据类型(FLOAT,REAL,DOUB ...

  7. mysql BDB支持表锁吗_mysql 表锁问题

    本文转自:http://www.cnblogs.com/itdragon/p/8194622.html MySQL 表锁和行锁机制 行锁变表锁,是福还是坑?如果你不清楚MySQL加锁的原理,你会被它整 ...

  8. MySQL单机并发量_mysql百万并发量-MySQL集群能支持100万个并发请求吗

    当然支持100万并发. 首先,我们必须做出决定,把阅读和写作分开. 然后,它取决于你需要分配多少个单元用于写作和阅读. 我的SQL集群不建议您使用它,因为有太多的错误. 所有这些都需要先进行压力测试. ...

  9. mysql支持中文_mysql数据库支持中文

    如果支持中文推荐将字符集设置成utf8可以一劳永逸,解决一些不必要的麻烦,对未来系统升级也可能有帮助.下面对设置方法进行列举 1.治标先治本,最好的方法就是在安装mysql的时候设置默认字符集为utf ...

  10. mysql循环插入语句_MySQL实现循环插入功能

    MySQL 不支持直接写SQL 语句实现循环插入功能. 想要实现该功能的方法有:用其他语言操控MySql或者用存储过程来实现两种. MySQL 不支持直接写SQL 语句实现循环插入功能. 想要实现该功 ...

最新文章

  1. Spring Security --SecurityConfig的详细配置
  2. 云合影程序_活动回顾丨阿里云ACE同城会开发者云workshop圆满落幕
  3. 带有Java DSL的Spring Integration MongoDB适配器
  4. 类型和原生函数及类型转换(一)
  5. Oracle_spatial的函数介绍
  6. 源代码电影涉及的计算机思想,关于电影源代码的结局解释
  7. SpringBoot前端Ajax以JSON格式获取后台数据
  8. python报告水印怎么弄_超简单Python安全批量打水印教程!
  9. python新浪api_python编程之API入门: (二)python3中使用新浪微博API
  10. 几何公差:GPS 2019 产品几何技术规范 (GDT)
  11. VirtualBox虚拟机安装MSDOS和MINIX2.0.0双系统
  12. Windows U盘插入出现位置不可用 无法访问 拒绝访问
  13. Python中的PV操作
  14. 旁观OpenGL里的透视投影矩阵
  15. 【每日蓝桥】2、一三年省赛Java组真题“组素数”
  16. 在线 xml转java对象_XML转Java实体对象
  17. 健康生活 - 四季蔬菜参考
  18. html字体颜色反色,根据背景颜色反转CSS字体颜色
  19. 迅为IMX6ULL开发板NFS服务器的搭建
  20. k重特征值必有k个线性无关的_大学线性代数必过复习资料

热门文章

  1. mysql spatial索引_空间索引Spatial Indexing
  2. OpenCV空间人工智能竞赛:第一部分
  3. 新浪微博相册图片外链限制,图床不显示解决方法总结!
  4. 《星际迷航*:舰桥船员》与虚拟现实新趋势
  5. Boom 3D 1.2.2 特别版 Mac 3D环绕音效增强工具
  6. 访问路由出现An error occurred
  7. 敞开拥抱中国,荷兰光刻机巨头ASML丝毫不受“大火”影响
  8. MySQL基本架构示意图
  9. Java SE 070 Retention及RetentionPolicy详解
  10. 给学妹学弟们的看书小建议!