MaxCompute 挑战使用SQL进行序列数据处理

简介: MaxCompute 挑战使用SQL进行序列数据处理 --而不是用MR和函数

日常编写数据加工任务,主要的方法就是使用SQL。第一是因为自己对SQL掌握的比较好(十多年数据开发经验,就这几个关键字,也不敢跟别人说自己不行),所以,MR和函数涉及不多。在接触MaxCompute这些年,写过的函数应该不超过10个,主要还是因为自己JAVA水平挫。记得早些年写过一个身份证号码校验函数,当时有个项目反馈一段SQL原来2分钟,使用我的函数就变成12分钟了。当时这个项目组还找到MaxCompute的研发,研发负责人又找到我,让我把我的代码调优下。我很惶恐啊,我是什么渣,我自己心里知道啊。最后还是厚着脸皮求研发帮我优化了下,性能终于改进了。这以后,我更不敢随机作函数了,毕竟MaxCompute官方建议尽可能使用SQL,SQL是优化过的方法,自己用MR和自定义函数性能是很难保障的。这也导致我至今在这方面也是渣渣,当然我认为错不在我,我只是听了“妈妈”的话而已。

最近很奇妙,接连有两个项目遇到了序列值计算的问题,还都是要求不能使用函数和MR。同事把问题送给我,我发现光读懂题都要半天(题目有点绕),不在一线搞开发太久了,有点生疏了。同样的问题,第一次搞了一天,第二次还搞了半天,没说很快能搞出来的,未免有点丢范。所以,总结出来跟大家分享下。

先说下什么是序列值的处理。表中的记录本身是无序的,但是业务上数据都是有序的,一般来说时间就是一个自然的序列。比如利用我一天的作息的时点记录,计算我一天吃了几次饭,吃了多久。乍一看,好像要写个函数。

问题模拟如下:

问题:吃了几次饭,都吃了多久?

条件:1-两个吃饭状态间隔在1小时内,算作一顿饭

2-最后一个吃饭状态后的下一个其他状态的开始时间,是吃饭的结束时间

image.png

通过上面的分析,我们可以得到结果:大约吃了四次饭,因为晚上吃饭的时间很长,按照规则算作吃了两次饭(第四次看起来是去撸串了)。我是怎么做的呢?第一步,我先把无关的信息剔除了,第1行、第4行、最后1行。第二步,后我利用数据是连续的时间的特质,找到了状态的结束时间。第三步,我识别了状态间隔1小时这个特征,识别出了一个“吃饭”中混杂的其他无关状态,并且还分析得到第三个“吃饭”和第四个“吃饭”状态是两个独立的状态。

那么用SQL怎么实现?排序是一定的了,要排序还要处理状态,必须使用窗口函数。能选的窗口函数似乎只有lag、lead。

窗口函数:

LAG  按偏移量取当前行之前第几行的值。

LEAD 按偏移量取当前行之后第几行的值。

官方文档:https://help.aliyun.com/document_detail/34994.html

即便有了这个函数,还有一个问题很头疼,函数需要指定偏移量,而这个问题里面并不知道到底会出现多少个状态。是不是也没有用呢?看看再说。

问题分解分解如下:

使用LAG\LEAD函数取到前一条记录和后一条记录的状态和时间,分析记录:

1-当前状态不是“吃饭”,上一个状态也不是“吃饭”,记录不保留。

2-当前状态不是“吃饭”,上一个状态是“吃饭”,为上一个状态提供结束时间,记录不保留。

3-当前状态是“吃饭”,记录上一个和下一个状态都是“吃饭”,记录不保留。

4-当前状态是“吃饭”,记录下一个状态时间,作为当前状态结束时间,记录保留。

如下图:

image.png

然后我们就得到了下面一个表格:

image.png

很明显,这不是我们最后需要的。虽然我们找到了状态为“吃饭”的行,并且通过窗口函数给它找到了状态的结束实际。但是表格还需要再作一次处理,才能变成我们想要的结果。再次使用LAG\LEAD函数,我们需要把间隔在1小时内的“吃饭”状态进行合并。

 

问题再次分解分解如下:

使用LAG\LEAD函数取到前一条记录和后一条记录的开始和结束时间,分析记录:

1-当前记录的“开始时间”减去上个时点的“结束时间”,如果小于1小时,该行记录不保留。这一行记录的状态需要与上一行合并为一次“吃饭”状态。下图中绿色标注行。

2-下个时点的“开始时间”减去当前记录的“结束时间”,如果小于1小时,该行记录与下一行记录合并。修改当前时点“吃饭”状态的结束时间为下一个时点的结束时间。下图橙色标注行。

image.png

然后我们得到了下面的表格:

image.png

不管之前我们想的多复杂,需要用什么循环或者递归逻辑实现,但是现在问题解决了。我们通过这个表格回答了最开始题目的问题。这个人吃过4次饭,开始时间分别是7点10分、12点25分、17点40分、19点45分,每次持续的时间大约都在1小时。这个过程就是一个找到需要的信息,剔除无关信息的过程,只不过这个where有点复杂。

其实从分析问题的角度来看,这个问题本身就有点复杂,搞懂问题一般都需要一定的时间。从实现问题的角度来看,使用高级语言JAVA或者python实现更容易点,循环撸一遍有什么解决不了的(一遍不够再来一遍)。用SQL实现,看起来有点复杂(可能是我常年使用SQL语言的原因,我觉得我好像分析问题的过程跟实现的过程是一样的。),但是代码量一定是最少的(性能可能也是最佳的)。再从可维护性上去综合比较,还是使用SQL实现更优。

所以,后面再遇到类似的问题,你应该可以搞定了。如果有点困难,至少你可以再回过头来看下这个例子,毕竟我花了好久来设计。

SQL问题解答:

with ta as(

select*

from values

(1001,'06:05:00','sleep')

,(1001,'07:10:00','eat')

,(1001,'08:15:00','phone')

,(1001,'11:20:00','phone')

,(1001,'12:25:00','eat')

,(1001,'12:40:00','phone')

,(1001,'13:30:00','eat')

,(1001,'13:35:00','sleep')

,(1001,'17:40:00','eat')

,(1001,'18:05:00','eat')

,(1001,'18:25:00','eat')

,(1001,'18:30:00','phone')

,(1001,'19:45:00','eat')

,(1001,'20:55:00','phone')

,(1001,'22:00:00','sleep')

t(id,stime,stat))

-- 5 计算根据前后记录的时间,判断记录是否要被合并

selectid,stime

,case whens2<=60 thenetime2 else etime end asetime,stat

from(

-- 4 计算前后记录的时间差

selectid,stime,etime,stat

,datediff(stime,etime1,'mi') ass1

,datediff(stime2,etime,'mi') ass2

,etime2

from(

-- 3 计算前后记录的时间

selectid,stime,etime,stat

,lag (stime,1) over(partition byid order by stime asc)as stime1

,lag (etime,1) over(partition byid order by stime asc)as etime1

,lead(stime,1) over(partition byid order by stime asc)as stime2

,lead(etime,1) over(partition byid order by stime asc)as etime2

from(

-- 2 识别前后记录状态,找到状态结束时间

selectid,stime,stat

,lead(stime,1) over(partition byid order by stime asc)as etime

,lag (stat,1) over(partition byid order by stime asc)as stat1

,lead(stat,1) over(partition byid order by stime asc)as stat2

from(

-- 1 把字符串转时间

selectid,to_date(concat('2021-06-29 ',stime),'yyyy-mm-dd hh:mi:ss') asstime,stat

fromta)t1)t2

wherestat='eat' and not(stat='eat' andstat1='eat' andstat2='eat'))t3)t4

wheres1 >60 ors1 is null

;

原文链接
本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/513031.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

低代码发展专访系列之四:低代码平台会带动企业的组织变革吗?

前言&#xff1a;2019年开始&#xff0c;低代码爆火。有人认为它是第四代编程语言&#xff0c;有人认为它是开发模式的颠覆&#xff0c;也有人认为是企业管理模式的变革……有很多声音&#xff0c;社区讨论很热烈。CSDN随后展开低代码平台产品系列活动&#xff0c;包括低代码开…

esclip直接快捷键构造函数_史上最全IntelliJ IDEA mac版快捷键文档

IntelliJ IDEA 是一款功能强大的Java IDE编辑器&#xff0c;支持java体系的web、客户端、安卓等开发。做为一款优秀的IDE&#xff0c;想要提高效率&#xff0c;最好是记住常用的快捷键&#xff0c;能让你事半功倍&#xff0c;小编整理了IDEA所有的快捷键&#xff0c;让你摆脱鼠…

禁止访问 共享计算机,win7如何禁止局域网用户访问电脑

为了方便共享资源&#xff0c;很多人都会设置网络共享文件夹&#xff0c;但是有些用户觉得在局域网内共享资源是件不安全的事情&#xff0c;那么win7如何禁止局域网用户访问电脑?这里小编就给大家分享一下win7旗舰版32位系统设置用户禁止访问局域网的方法。win7如何禁止局域网…

基于实时深度学习的推荐系统架构设计和技术演进

简介&#xff1a; 整理自 5 月 29 日 阿里云开发者大会&#xff0c;秦江杰和刘童璇的分享&#xff0c;内容包括实时推荐系统的原理以及什么是实时推荐系统、整体系统的架构及如何在阿里云上面实现&#xff0c;以及关于深度学习的细节介绍 本文整理自 5 月 29 日阿里云开发者大会…

阿里云肖力:跳过量变过程的安全质变

简介&#xff1a; 作者肖力从事网络安全工作将近20年&#xff0c;处理过各类攻击威胁&#xff0c;经历了云下云上安全的建设。云计算的安全工作从10年前开始&#xff0c;他们搭建了阿里云平台的防护体系&#xff0c;帮助各行业用户在云上构建企业安全能力。云原生的出现进一步加…

echarts bar 控制大小_echarts基本配置参数

网址&#xff1a;https://www.echartsjs.com/zh/tutorial.html#5%20%E5%88%86%E9%92%9F%E4%B8%8A%E6%89%8B%20ECharts五分钟上手 基本配置1.矩形参数<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name&q…

opencv opencl加速_回放 | OpenCV Webinar 3:OpenCV深度学习应用与原理分析

OpenCV DNN模块提供了深度学习的推理&#xff0c;支持Caffe、Tensoflow、Torch、Darknet、ONNX等格式的模型&#xff0c;无需用户安装对应的深度学习框架&#xff0c;也无需进行模型格式转换&#xff0c;直接调用DNN模块接口即可创建深度学习应用。DNN模块自2017年8月3.3版本从…

云原生架构应该怎么设计?

简介&#xff1a; 阿里巴巴为大量各行各业的企业客户提供了基于阿里云服务的解决方案和最佳实践&#xff0c;以帮助企业完成数字化转型&#xff0c;并积累了大量经验和教训。阿里巴巴将企业的核心关注点、企业组织与 IT 文化、工程实施能力等多个方面与架构技术相结合&#xff…

360数科知微实验室发布反诈报告:揭秘黑灰产数据流转真相

近日&#xff0c;360数科旗下信息安全知微实验室通过反诈分析研究&#xff0c;追踪溯源网络黑灰产数据非法交易链条&#xff0c;发布系列反诈研究《黑灰产数据流转分析报告》&#xff08;以下简称“报告”&#xff09;。报告称&#xff0c;目前在网络黑产平台流转的数据主要来源…

【详谈 Delta Lake 】系列技术专题 之 Streaming(流式计算)

简介&#xff1a; 本文翻译自大数据技术公司 Databricks 针对数据湖 Delta Lake 的系列技术文章。众所周知&#xff0c;Databricks 主导着开源大数据社区 Apache Spark、Delta Lake 以及 ML Flow 等众多热门技术&#xff0c;而 Delta Lake 作为数据湖核心存储引擎方案给企业带来…

jdbc驱动程序_JDBC操作数据库的步骤

package mysql;import java.sql.Connection;import java.sql.Driver;import java.sql.DriverManager;/** JDBC操作数据库的步骤* 1.注册驱动* 告知JVM使用的是哪一个数据库驱动* 2.获得连接* 使用JDBC中的类&#xff0c;完成对Mysql数据库连接* 3.获得语句执行平台* 通过连接对…

一睹为快 | 施耐德电气全生命周期智能制造解决方案亮相线上工博

作家瓦科拉夫斯米尔在《国家繁荣为什么离不开制造业》曾说过&#xff1a;“制造业始终是技术创新的基本源泉&#xff0c;也是经济增长的原动力。” 反过来看&#xff0c;技术创新该如何推动制造业的发展&#xff0c;从而促进经济增长呢&#xff1f; 12 月 1 日&#xff0c;在…

教程系列——用模板快速生成《客户意见反馈表》

简介&#xff1a; 【开箱即用的模板使用系列教程】将会手把手教给大家如何快速启用钉钉宜搭提供各类模板。今天第二讲&#xff0c;介绍《客户意见反馈表》的模板启用。 【开箱即用的模板使用系列教程】将会手把手教给大家如何快速启用钉钉宜搭提供各类模板。今天第1讲&#xff…

重温设计模式之 Factory

简介&#xff1a; 创建型模式的核心干将&#xff0c;工厂、简单工厂、抽象工厂&#xff0c;还记得清么&#xff0c;一文回顾和对比下。 作者 | 弥高 来源 | 阿里技术公众号 前言 创建型模式的核心干将&#xff0c;工厂、简单工厂、抽象工厂&#xff0c;还记得清么&#xff0c…

云端上的字节,引擎火力全开

作者 | 贾凯强出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;十二月&#xff0c;在产业最震撼的一条消息莫过于字节跳动旗下火山引擎终于出云产品了。字节跳动的业务早已跑在云上&#xff0c;这早已是行业公开的信息。可是这朵云究竟有多大呢&#xff1f;在…

收件服务器信息,收件服务器配置信息

收件服务器配置信息 内容精选换一换SAP HANA运行在SAP HANA云服务器上。需要根据部署场景&#xff0c;创建一台或多台HANA云服务器&#xff0c;用于部署SAP HANA软件。请参见方案和数据规划相关章节&#xff0c;确定HANA云服务器数量及相关规划信息。在集群场景下创建多台HANA云…

Nacos 2.0 升级前后性能对比压测

简介&#xff1a; Nacos 2.0 通过升级通信协议和框架、数据模型的方式将性能提升了约 10 倍&#xff0c;解决继 Nacos 1.0 发布逐步暴露的性能问题。本文通过压测 Nacos 1.0&#xff0c;Nacos 1.0 升级 Nacos 2.0 过程中&#xff0c;Nacos 2.0 进行全面性能对比&#xff0c;直观…

深入浅出讲解MSE Nacos 2.0新特性

简介&#xff1a; 随着云原生时代的到来&#xff0c;微服务已经成为应用架构的主流&#xff0c;Nacos也凭借简单易用、稳定可靠、性能卓越的核心竞争力成为国内微服务领域首选的注册中心和配置中心&#xff1b;Nacos2.0更是把性能做到极致&#xff0c;让业务快速发展的用户再也…

交换机是如何对数据包打标签去标签的_条形码软件如何在标签纸上套打可变条码...

在制作商品标签时&#xff0c;通常会遇到标签纸上已经有部分内容&#xff0c;需要我再添加打印一些对应的信息(如下图)&#xff0c;那么这种情况下&#xff0c;如何比较简单的在合适位置上打印可变条码呢&#xff0c;下面我们就来详细看一下在中琅条形码软件中套打可变条码的操…

学不动也要学!ViewPager2 新特性

作者 | tech-bus.丹卿来源 | 程序员八十前 言浏览Android开发者官网的时候&#xff0c;发现Google竟然曾经悄悄推出过一个新的控件:ViewPager2;从名字上看就知道是ViewPager的升级版本&#xff0c;看了下推出这个控件的时间&#xff0c;早在2019年2月7号Google就已经发布了&…