mysql分析函数的实现

今天收到同事的一需求,要求实现以下功能:

drop table test;

create table test(name varchar(10),name1 varchar(10),count bigint);

delete from test;

insert into test values(‘1′,’a’,2);

insert into test values(‘1′,’b’,1);;

insert into test values(‘1′,’c’,4);

insert into test values(‘1′,’d’,5);

insert into test values(‘1′,’e’,7);

insert into test values(‘1′,’f’,8);

insert into test values(‘2′,’g’,9);

insert into test values(‘2′,’h’,0);

insert into test values(‘2′,’i’,21);

insert into test values(‘2′,’j’,3);

insert into test values(‘2′,’k’,4);

insert into test values(‘2′,’l’,56);

insert into test values(‘3′,’m’,67);

insert into test values(‘3′,’n’,89);

insert into test values(‘3′,’o’,12);

insert into test values(‘3′,’p’,22);

insert into test values(‘3′,’q’,23);

insert into test values(‘3′,’r’,42);

insert into test values(‘3′,’s’,26);

 

根据name字段分组,取出改组内的前4项,并且按照count字段进行降序排序,由于mysql没有oracle中的分析函数,看上去很简单的需求,但是折腾了许久,还是没有实现,于是乎在网上收罗了一下mysql分析函数是怎么实现的 ,找到了mysql分析函数的解决办法,学习了一下,于是乎把同事的功能实现了;

select name, name1, count  from (select b.name, b.name1, b.count,

if(@name = b.name, @rank := @rank + 1, @rank := 1) as rank,@name:=b.name

from (select name, name1, count    from test order by name asc, count desc) b,

(select @rownum := 0, @name := null, @rank := 0) a) result where rank<5;

| name | name1 | count |

+——+——-+——-+

| 1    | f     |     8 |

| 1    | e     |     7 |

| 1    | d     |     5 |

| 1    | c     |     4 |

| 2    | l     |    56 |

| 2    | i     |    21 |

| 2    | g     |     9 |

| 2    | k     |     4 |

| 3    | n     |    89 |

| 3    | m     |    67 |

| 3    | r     |    42 |

| 3    | s     |    26 |

+——+——-+——-+

12 rows in set (0.02 sec)

如果上面的sql初次看到有些让人摸不着头脑的话,你可以看看他的执行计划,然后从执行计划得到一些执行流程,该sql中最核心的技术点为使用自定义变量来保存sql执行过程中的值:

if(@name = b.name, @rank := @rank + 1, @rank := 1) as rank,@name:=b.name

这条判断语句对下面结果进行处理,并生成rank,由于下面查询的结果中对name做了排序,所以@name:=b.name使的相同name值的rank能够递增;

+—-+————-+————+——–+—————+——+———+——+——+—————-+

| id | select_type | table      | type   | possible_keys | key  | key_len | ref  | rows | Extra          |

+—-+————-+————+——–+—————+——+———+——+——+—————-+

|  1 | PRIMARY     | <derived2> | ALL    | NULL          | NULL | NULL    | NULL |   19 | Using where    |

|  2 | DERIVED     | <derived4> | system | NULL          | NULL | NULL    | NULL |    1 |                |

|  2 | DERIVED     | <derived3> | ALL    | NULL          | NULL | NULL    | NULL |   19 |                |

|  4 | DERIVED     | NULL       | NULL   | NULL          | NULL | NULL    | NULL | NULL | No tables used |

|  3 | DERIVED     | test       | ALL    | NULL          | NULL | NULL    | NULL |   19 | Using filesort |

 

如果你对下面的select @rownum := 0, @name := null, @rank := 0看不太明白,可以改写一下sql:

select name, name1, count  from (select b.name, b.name1,b.count,

if(@name = b.name, @rank := @rank + 1, @rank := 1) as rank,@name:=b.name

from (select name, name1, count,@rownum := 0, @name := null, @rank := 0

from test order by name asc, count desc) b) result where rank<4;

+—-+————-+————+——+—————+——+———+——+——+—————-+

| id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows | Extra          |

+—-+————-+————+——+—————+——+———+——+——+—————-+

|  1 | PRIMARY     | <derived2> | ALL  | NULL          | NULL | NULL    | NULL |   19 | Using where    |

|  2 | DERIVED     | <derived3> | ALL  | NULL          | NULL | NULL    | NULL |   19 |                |

|  3 | DERIVED     | test       | ALL  | NULL          | NULL | NULL    | NULL |   19 | Using filesort |

+—-+————-+————+——+—————+——+———+——+——+—————-+
时间: 2024-09-15 10:52:23

mysql分析函数的实现的相关文章

PHP的XML分析函数(转) (介绍这个PHP里的XML分析函数的文章可不太有哦。。 看过这篇就应该清楚点了吧...

xml|函数 PHP的XML分析函数 首先我得承认我喜欢计算机标准.如果每个人都遵从这个行业的标准,互联网将会是一个更好的媒体.使用标准化的数据交换格式才能使开放的和独立于平台的计算模式切实可行.这就是我作为XML爱好者的原因. 幸运的是,我最喜爱的脚本语言不但支持XML而且对其支持正不断加强.PHP可以让我迅速将XML文档发布到互联网上,收集XML文档的统计信息,将XML文档转换成其它格式.例如,我时常用PHP的XML处理能力来管理我用XML所写的文章和书. 本文中,我将讨论任何用PHP内建的

ORACLE分析函数(7) 自定义聚合函数

oracle为我们提供了非常丰富的聚合函数,如SUM\AVG\MAX等.除此之外,我们还可以编写自己的聚合函数,当然,自定义聚合函数也可以作为分析函数来使用. 自定义聚合函数与oracle内置聚合函数并无太大区别,而且它可以使用任何oracle支持的语言来编写,如PL/SQL\C\C++\JAVA.在本文中,我们以PLSQL为开发语言,尝试编制我们自己的聚合函数. 编制ORACLE支持的自定义聚合函数,自然要依据oracle指定的规则来编写,我们不妨称之为ODCIAggregate规则.下面我们

HTAP数据库——HybirdDB for MySQL产品和典型方案介绍

随着DT时代的到来,企业占有的数据越来越多,其规模可能达到上百TB甚至PB级,如何以合理的成本管理并维护这样一个数据库也成为各个企业IT管理中的核心问题.HybirdDB for MySQL是基于HTAP资源的数据库,同时支持OLTP,在一份数据上做事务,又支持实时分析.10月12日的云栖大会·HTAP技术专场中,阿里云产品专家陈琢分享了阿里云自研的HTAP数据库,并重点分享了相关技术及实现.如何借助HTAP技术解决业务痛点等内容. 本文分享的内容主要包括五个部分,首先是阿里云数据库产品团队的情

TokuDB · 引擎特性 · HybridDB for MySQL高压缩引擎TokuDB 揭秘

HybridDB for MySQL(原名petadata)是面向在线事务(OLTP)和在线分析(OLAP)混合场景的关系型数据库.HybridDB采用一份数据存储来进行OLTP和OLAP处理,解决了以往需要把一份数据多次复制来分别进行业务交易和数据分析的问题,极大地降低了数据存储的成本,缩短了数据分析的延迟,使得实时分析决策称为可能. HybridDB for MySQL兼容MySQL的语法及函数,并且增加了对Oracle常用分析函数的支持,100%完全兼容TPC-H和TPC-DS测试标准,从

从Oracle转到Mysql前需了解的50件事

1. 对子查询的优化表现不佳. 2. 对复杂查询的处理较弱 3. 查询优化器不够成熟 4. 性能优化工具与度量信息不足 5. 审计功能相对较弱 6. 安全功能不成熟,甚至可以说很粗糙.没有用户组与角色的概念,没有回收权限的功能(仅仅可以授予权限).当一个用户从不同的主机/网络以同样地用户名/密码登录之后,可能被当作完全不同的用户来处理.没有类似于Oracle的内置的加密功能. 7.身份验证功能是完全内置的.不支持LDAP,Active Directory以及其它类似的外部身份验证功能. 8.My

PostgreSQL 与 MySQL 相比,优势何在?

一. PostgreSQL 的稳定性极强, Innodb 等引擎在崩溃.断电之类的灾难场景下抗打击能力有了长足进步,然而很多 MySQL 用户都遇到过Server级的数据库丢失的场景--mysql系统库是MyISAM的,相比之下,PG数据库这方面要好一些. 二.任何系统都有它的性能极限,在高并发读写,负载逼近极限下,PG的性能指标仍可以维持双曲线甚至对数曲线,到顶峰之后不再下降,而 MySQL 明显出现一个波峰后下滑(5.5版本之后,在企业级版本中有个插件可以改善很多,不过需要付费). 三.PG

MySQL和Oracle开发差异

1)  数据类型差异 Oracle MySQL 注释 单独创建序列来实现 自动增长的数据类型   varchar2 varchar   number tinyint,smallint,mediumint,int,bigint float,double   clob text,mediumtext,longtext   date datetime   无 enum   raw binary(n),varbinary(n)   无 bit(n)   blob blob,mediumblob,long

HybridDB for MySQL 实现在线与离线数据分离的实践

本文将重点介绍HybridDB for MySQL 实现在线与离线数据分离的实践,特别推荐! 核心业务简介 任务中心汇聚了集团的所有工作流任务,并提供统一的入口给用户处理集团的工作任务. 面临主要问题 1.单表存储量超高目前已有4千万的数据,并且在急速的增长.预计年增长在200%以上. 2.业务需要大范围的查询由于业务需要查询多张表,比如查询在线,再查离线表.而且频率和复杂度在提升.会导致慢sql的出现. 如何架构改造 在线数据与离线数据隔离,在数据访问层面不相互影响  在线数据到离线数据必须实

SQL获取第一条记录的方法(sqlserver、oracle、mysql数据库)_MsSql

Sqlserver 获取每组中的第一条记录 在日常生活方面,我们经常需要记录一些操作,类似于日志的操作,最后的记录才是有效数据,而且可能它们属于不同的方面.功能下面,从数据库的术语来说,就是查找出每组中的一条数据.下面我们要实现的就是在sqlserver中实现从每组中取出第一条数据. 例子 我们要从上面获得的有效数据为: 对应的sql语句如下所示: select * from t1 t where id = (select top 1 id from t1 where grp = t.grp o