mysql topn_TopN语句

2023-11-14

TopN语句常用于计算实时数据中对某个指标的最大或者最小的前N个数据的筛选。Flink SQL可以基于 OVER窗口操作灵活地完成TopN的工作。

语法

SELECT*

FROM(

SELECT*,

ROW_NUMBER()OVER([PARTITION BY col1[,col2..]]

ORDER BY col1[asc|desc][,col2[asc|desc]...])AS rownum

FROM table_name)

WHERE rownum<=N[AND conditions]

参数说明:

ROW_NUMBER():行号计算函数OVER的窗口,行号计算从1开始。

PARTITION BY col1[, col2..] : 指定分区的列,可以不指定。

ORDER BY col1 [asc|desc][, col2 [asc|desc]...]:指定排序的列和每列的排序方向。

如上语法所示,TopN需要两层query。

查询中使用 ROW_NUMBER() 窗口函数来对数据根据排序列进行排序并标上排名。

外层查询中对排名进行过滤,只取前N条。例如N=10即为取前10条的数据。

在执行过程中,Flink SQL会对输入的数据流根据排序键进行排序。如果某个分区的前N条记录发生了改变,则会将改变的那几条数据以更新流的形式发给下游。

注意:如果需要将TopN的数据输出到外部存储,后接的结果表必须是一个带主键的表。

WHERE条件的限制

为了使Flink SQL能识别出这是一个TopN的query,外层循环中必须要指定 rownum <= N的格式来指定前N条记录,不能使用rownum - 5 <= N 这种将rownum至于某个表达式中。当然,WHERE条件中,可以额外带上其他条件,但是必须是以AND连接。

示例一

如下示例,先统计查询流中每小时、每个城市和关键字被查询的次数。然后输出每小时、每个城市被查询最多的前100个关键字。在输出表中,小时、城市、排名三者可以唯一确定一条记录,所以需要将这三列声明成联合主键(需要在外部存储中也有同样的主键设置)。

CREATE TABLE rds_output(

rownumint,

start_time bigint,

city varchar,

keyword varchar,

pv bigint,

PRIMARY KEY(rownum,start_time,city)

)with(

type='rds',

...

)

INSERT INTO rds_output

SELECT rownum,start_time,city,keyword,pv

FROM(

SELECT*,

ROW_NUMBER()OVER(PARTITION BY start_time,city ORDER BY pv desc)AS rownum

FROM(

selectsubstr(time_str,1,12)asstart_time,

keyword,

count(1)aspv,

city

fromtmp_search

groupbysubstr(time_str,1,12),keyword,city

)a

)

WHERE rownum<=100

示例二

测试数据

ip(varchar)

time(varchar)

192.168.1.1

100000000

192.168.1.2

100000000

192.168.1.2

100000000

192.168.1.3

100030000

192.168.1.3

100000000

192.168.1.3

100000000

测试语句

create table source_table(

IP VARCHAR,

`TIME`VARCHAR

)with(

type='datahub',

endPoint='http://dh-cn-hangzhou.aliyuncs.com',

project='blink_test',

topic='ip_count01',

accessId='LTXXXx',

accessKey='gUqXXXxxx'

);

create table result_table(

rownumint,

start_time VARCHAR,

IP VARCHAR,

cc BIGINT,

PRIMARY KEY(start_time,IP)

)with(

type='rds',

url='jdbc:mysql://rm-bp1gz4k202t8XXXXXXs.com:3306/blink_test',

tableName='blink_rds_test',

userName='xxx',

password='xxx'

);

INSERT INTO result_table

SELECT rownum,start_time,IP,cc

FROM(

SELECT*,

ROW_NUMBER()OVER(PARTITION BY start_time ORDER BY cc desc)AS rownum

FROM(

SELECT SUBSTRING(`TIME`,1,2)AS start_time,--可以根据真实时间取相应的数值,这里取得是测试数据

COUNT(IP)AS cc,

IP

FROM source_table

GROUP BY SUBSTRING(`TIME`,1,2),IP

)a

)

WHERE rownum<=3--可以根据真实top值取相应的数值,这里取得是测试数据

测试结果

rownum(int)

start_time(varchar)

ip(varchar)

cc(bigint)

1

10

192.168.1.3

6

2

10

192.168.1.2

4

3

10

192.168.1.1

2

无排名优化

根据TopN的语法,rownum字段会作为结果表的主键字段之一写入结果表。但是这可能导致数据膨胀的问题。例如,收到一条原排名9的更新数据,更新后排名上升到1,那么从1到9的数据排名都发生变化了。需要将这些数据作为更新都写入结果表。这样就产生了数据膨胀,可能导致结果表因为收到了太多的数据而降低更新速度。

优化方法

结果表中不保存 rownum,最终的 rownum 由前端计算。因为TopN的数据量通常不会很大,前端排序100个数据很快。当收到一条原排名9,更新后排名上升到1的数据,也只需要发送这一条数据,而不用把排名1到9的数据全发送下去。这种优化能够提升结果表的更新速度。

无排名优化语法

SELECT col1,col2,col3

FROM(

SELECT col1,col2,col3

ROW_NUMBER()OVER([PARTITION BY col1[,col2..]]

ORDER BY col1[asc|desc][,col2[asc|desc]...])AS rownum

FROM table_name)

WHERE rownum<=N[AND conditions]

语法与上文类似,只是在外层查询中将 rownum 字段裁剪掉即可。

注意:在无 rownum 的场景,结果表主键的定义一定要特别注意。如果定义有误,会直接导致TopN结果的不正确。无 rownum 场景的主键应为 TopN 上游 group by 节点的 keys 列表。

无排名优化示例

本示例来自某视频行业用户的真实业务(精简后)。用户每个视频在分发时会产生大量流量,依据视频产生的流量可以分析出最热门的视频。如下示例用于统计出每分钟流量最大的 top5 的视频。

测试语句

--从SLS读取数据原始存储表

CREATE TABLE sls_cdnlog_stream(

vid VARCHAR,--video id

rowtimeTimestamp,--观看视频发生的时间

response_size BIGINT,--观看产生的流量

WATERMARK FOR rowtimeaswithOffset(rowtime,0)

)WITH(

type='sls',

...

);

--1分钟窗口统计vid带宽数

CREATE VIEW cdnvid_group_view AS

SELECT vid,

TUMBLE_START(rowtime,INTERVAL'1'MINUTE)AS start_time,

SUM(response_size)AS rss

FROM sls_cdnlog_stream

GROUP BY vid,TUMBLE(rowtime,INTERVAL'1'MINUTE);

--存储表

CREATE TABLE hbase_out_cdnvidtoplog(

vid VARCHAR,

rss BIGINT,

start_time VARCHAR,

--注意结果表中不存储rownum字段

--特别注意该主键的定义,为TopN上游groupbykeys

PRIMARY KEY(start_time,vid)

)WITH(

type='RDS',

...

);

--统计每分钟top5消耗流量的vid,并输出

INSERT INTO hbase_out_cdnvidtoplog

--注意次外层查询,不选出rownum字段

SELECT vid,rss,start_time FROM

(

SELECT

vid,start_time,rss,

ROW_NUMBER()OVER(PARTITION BY start_time ORDER BY rss DESC)asrownum,

FROM

cdnvid_group_view

)

WHERE rownum<=5;

测试数据

vid(VARCHAR)

rowtime(Timestamp)

response_size(BIGINT)

10000

2017-12-18 15:00:10

2000

10000

2017-12-18 15:00:15

4000

10000

2017-12-18 15:00:20

3000

10001

2017-12-18 15:00:20

3000

10002

2017-12-18 15:00:20

4000

10003

2017-12-18 15:00:20

1000

10004

2017-12-18 15:00:30

1000

10005

2017-12-18 15:00:30

5000

10006

2017-12-18 15:00:40

6000

10007

2017-12-18 15:00:50

8000

测试结果

start_time(VARCHAR)

vid(VARCHAR)

rss(BIGINT)

2017-12-18 15:00:00

10000

9000

2017-12-18 15:00:00

10007

8000

2017-12-18 15:00:00

10006

6000

2017-12-18 15:00:00

10005

5000

2017-12-18 15:00:00

10002

4000

本文转自实时计算——

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mysql topn_TopN语句 的相关文章

随机推荐

  • 适用于小白-vs2019的下载与安装

    学习c语言时 少不了编译器的使用 那么传统的dev c 过于古老的同时 也不再更新 而大学授课老师一般要求安装vc 6 0 学校机房也一般为vc 6 0 但这两种都还是过于古老 现在机构授课过程一般采用vs2019 使用起来更加便捷 清晰
  • 将CelebA数据集所给标签转化为MTCNN中训练集所需标签

    img dir r D datasets CelebA Img img celeba 7z img celeba anno src r D datasets CelebA Anno list bbox celeba txt anno lan
  • Oracle数据库索引管理-基于函数索引ORA-30553

    在ORACALE数据库中 创建函数索引时 若函数是自定义的函数 须在定义函数时加上deterministic关健字 不然会出现 函数不确定 的错误提示 创建函数索引 ORA 30553 函数不确定 原函数如下 create or repla
  • Hibernate HQL绑定变量

    Hibernate HQL查询 插入 更新 update 实例 1 实体查询 有关实体查询技术 其实我们在先前已经有多次涉及 比如下面的例子 String hql from User user List list session Creat
  • 毕业设计 - 个人博客系统的设计与实现【源码+论文】

    文章目录 前言 一 项目设计 1 模块设计 博主功能用例 游客功能用例 2 实现效果 二 部分源码 项目源码 前言 今天学长向大家分享一个 Java web 毕业设计 项目 个人博客系统的设计与实现 一 项目设计 1 模块设计 博主功能用例
  • Linux驱动_多点电容触摸

    一丶Linux下多点电容触摸驱动框架 电容触摸屏IC是FT5426 为IIC协议芯片 因此需要编写IIC驱动 触摸IC会发出中断信号 并在中断服务函数中上报信息 因此需要编写中断框架 触摸屏向Linux内核上报的信息都属于Input子系统
  • 基于Unity3d 引擎的Android游戏优化

    最近项目进入收尾阶段 之前对项目做了很多优化 mesh合并 减少DrawCall和模型骨骼以及物理计算 合并材质球 优化代码等等 在IOS上还好 但是Android上 试过几款手机 从低端到高端 发现性能还是很差 所以又花了几天来研究摸索
  • C#中索引器

    C 中索引器和数组的使用类似 public class Test private readonly string name new string 10 public string this int index get return name
  • 【论文速览】根据人脑fMRI信号重建图像 Image Reconstruction from human brain activity

    文章目录 前言 文章一 研究背景 主要方法 部分实验结果 总结与思考 参考资料 文章二 研究背景 主要方法 部分实验结果 总结与思考 前言 人类的视觉神经系统对于真实世界的视觉刺激有着非凡的感知与理解能力 比如我们能够准确地识别物体距离和三
  • (java 基础知识) Java 安全套接字--javax.net.ssl

    有关SSL的原理和介绍在网上已经有不少 对于Java下使用keytool生成证书 配置SSL通信的教程也非常多 但如果我们不能够亲自动手做一个SSL Sever和SSL Client 可能就永远也不能深入地理解Java环境下 SSL的通信是
  • leetcode-2 Add Two Numbers(两数相加)

    题目描述 给出两个 非空 的链表用来表示两个非负的整数 其中 它们各自的位数是按照 逆序 的方式存储的 并且它们的每个节点只能存储 一位 数字 如果 我们将这两个数相加起来 则会返回一个新的链表来表示它们的和 您可以假设除了数字 0 之外
  • 下一个区块链风口必备——跨链互操作

    Moonbeam是首个原生的跨链消息开发者平台 旨在通过结合波卡生态独有的XCM技术和Moonbeam首创的预编译技术为用户带来无缝且丝滑的跨链互操作性体验 让用户在无意中享受多链部署带来特色的同时消除链与链之间的隔阂 除外 Moonbea
  • uboot启动流程分析

    FS4412 SOC的启动过程 在图中有 Cortax A9 其是芯片核心 也就是中央处理器 CPU Internal Rom 是一个只读存储器 里面存储了代码 总大小为64K 它的功能是用于读写pin脚 其作用是用来告诉系统从何处去读取u
  • #13文献学习--边缘计算的计算卸载建模综述

    文献 A survey on computation offloading modeling for edge computing 一 介绍 边缘计算 在网络边缘 代表云服务的下游数据和代表物联网服务的上游数据上执行计算 优势 计算或云计算
  • 【react】state的总结

    state是组件对象最重要的属性 值是对象 组件被称为 状态机 通过更新组件的state来更新对应的页面显示 重新渲染组件 组件中render方法中的this指向组件的实例对象 组件自定义的方法中的this指向undefined 如何解决
  • ffpmeg相对无损转换mkv到mp4,保留标签、封面等元数据

    其实这个无损是相对无损 不是绝对无损 因为mkv封装支持的格式 标签等是比mp4封装要多的 比如mkv可以封装wav音频 mp4不能封装wav音频 所以这里的无损的前提是该mkv的媒体流 标签 TAG 封面图等 都是Mp4本身支持的 才能无
  • 图(基本概念)

    本章重点 图的基本概念和基本性质 图的存储结构 邻接矩阵 邻接表 邻接多重表 十字链表 及其特性 存储结构之间的转化 基于存储结构上的遍历操作和各种应用 拓扑排序 最小生成树 最短路径 关键路径 等 算法难度大 主要掌握深度优先搜索和广度优
  • otsu算法

    otsu法 最大类间方差法 有时也称之为大津算法 使用的是聚类的思想 把图像的灰度数按灰度级分成2个部分 使得两个部分之间的灰度值差异最大 每个部分之间的灰度差异最小 通过方差的计算来寻找一个合适的灰度级别 来划分 所以 可以在二值化的时候
  • 【Redis】缓存问题

    用户数据一般都是存储在数据库中 数据库则落在磁盘上 而磁盘的I O速度是计算机中最慢的硬件 当用户的访问量在某一个时间段突然上升 数据库就很容易崩溃 为了避免用户直接访问数据库 所以会使用缓存数据库 Redis 作为缓冲层 Redis 是内
  • mysql topn_TopN语句

    TopN语句常用于计算实时数据中对某个指标的最大或者最小的前N个数据的筛选 Flink SQL可以基于 OVER窗口操作灵活地完成TopN的工作 语法 SELECT FROM SELECT ROW NUMBER OVER PARTITION