当前位置: 首页 > 编程日记 > 正文

算法人必懂的进阶SQL知识,4道面试常考题

640?wx_fmt=jpeg
(图片付费下载自视觉中国)
作者 | 石晓文
来源|小小挖掘机(ID:wAlsjwj)
近期在不同群里有小伙伴们提出了一些在面试和笔试中遇到的Hive SQL问题,Hive作为算法工程师的一项必备技能,在面试中也是极有可能被问到的,所以有备无患,本文将对这四道题进行详细的解析,还是有一定难度的,希望你看完本文能够有所收获。

1、多列转多行

第一道题目是这样的:
假设现有一张Hive表,
元数据格式为:字段:
id    stirng
tim    string数据格式如下:
a,b,c,d 2:00,3:00,4:00,5:00
f,b,c,d    1:10,2:20,3:30,4:40需要变成:
a     2:00
b     3:00
c     4:00
d     5:00
这道题目是需要把多行转换成多行,有点类似python里面的zip操作。大伙应该都知道hive里有一个常用的一行转多行的函数叫explode,假设有如下的数据:
a,b,c,d 2:00,3:00,4:00,5:00
f,b,c,d    1:10,2:20,3:30,4:40
按照第二列explode的话,使用下面的SQL:
selectid,tim,single_tim
fromdefault.a1lateral view explode(split(tim,',')) t as single_tim
效果如下:

640?wx_fmt=png

但这道题目里,需要对两列同时进行explode,如果只进行简单的explode,效果如下:

640?wx_fmt=png

这样一行变成了16行,而我们仅仅需要的是其中能够对齐下标的四行。所以在进行explode的时候,我们期望不仅仅能够能够获得数组里的每个值,还希望能够得到其对应的下标,这样在对两列同时进行explode的时候,保留数组下标相同的四行就可以了。这里我们会用到posexplode函数。
posexplode函数跟explode函数的使用方法类似,看下面的例子:
selectid,tim,single_id_index,single_id
fromdefault.a1lateral view posexplode(split(id,',')) t as single_id_index,single_id
返回的结果为:

640?wx_fmt=png

应用到本题,只需要应用两次posexplode函数,再通过where留下两个index相等的行就可以了,按照这个思路,sql如下:
selectid,tim,single_id,single_tim
fromdefault.a1lateral view posexplode(split(id,',')) t as single_id_index,single_idlateral view posexplode(split(tim,',')) t as single_tim_index,single_tim
wheresingle_id_index = single_tim_index
结果正是我们想要的:

640?wx_fmt=png


2、排序后相邻两行均值

第二题的原始数据如下:

640?wx_fmt=png

要求如下:

640?wx_fmt=png

分组排序想必大家都知道使用row_number()函数,但要找到同组前一行的值,可能有许多同学不太了解,这里是用的是lead/lag函数,两个函数用法如下:
lag(字段名,N) over(partition by 分组字段 order by 排序字段 排序方式)lead(字段名,N) over(partition by 分组字段 order by 排序字段 排序方式)
lag括号里理由两个参数,第一个是字段名,第二个是数量N,这里的意思是,取分组排序之后比该条记录序号小N的对应记录的指定字段的值,如果字段名为ts,N为1,就是取分组排序之后上一条记录的ts值。
lead括号里理由两个参数,第一个是字段名,第二个是数量N,这里的意思是,取分组排序之后比该条记录序号大N的对应记录的对应字段的值,如果字段名为ts,N为1,就是取分组排序之后下一条记录的ts值。
如果没有前一行或者后一行,对应的字段值为null。
所以,这里我们应该使用的是lag函数,来获取同组排序后前一行数据对应字段的值,SQL如下:
selectyear,chr,if(pre_val is null,val,(val + pre_val) / 2.0) as avg_val
from
(
selectyear,chr,val,lag(val,1) over(partition by year order by chr asc) as pre_val
fromdefault.a2
) a
注意这里的一个小细节,如果分组后数据排在第一位,它是没有前一个数的,此时数仍保持原样,所以这里加了一个if判断,结果符合预期:

640?wx_fmt=png


3、获取字符串索引列表

第三题的题目要求如下:
1011
0101
=> 取到每一行中1所对应的索引列表,索引从1开始
0101    2,4
1011    1,3,4
这一行其实也是对posexplode方法的应用,直接上代码:
selectid,stri,concat_ws(',',collect_list(index)) as indices
from
(selectid,stri,chr,cast(index + 1 as string) as indexfromdefault.abcglateral view posexplode(split(stri,'')) ids as index,chrwherechr = '1'
) a
group byid,stri


4、分块排序

最后一题感觉是比较有难度的一道题目:
2014,1
2015,1
2017,0
2018,0
2019,1
2020,1
2021,1
2022,0
2023,0
=>
2014,1,1
2015,1,2
2017,0,1
2018,0,2
2019,1,1
2020,1,2
2021,1,3
2022,0,1
2023,0,2
简单描述下题目,col1是有序的,然后按照col2分块计数,每当col2发生变化,就重新开始计数,计数的结果当作col3返回。
这道题我想到的方法可能比较笨,先上代码,然后咱们一步步解析:
select year,num,row_number() over(partition by min_year order by year asc) as new_rankfrom(select year,base.num as num,min_year,row_number() over(partition by base.year order by min_year desc) as rankfrom (select *from default.a3) baseinner join (select min_year,num,pre_numfrom (select year as min_year,num,lag(num,1) over(order by year) as pre_numfrom default.a3) awhere num!=pre_numor pre_num is null) min_yearon base.num = min_year.numwhere base.year >= min_year.min_year) ccwhere rank = 1order by year
输出结果符合预期:

640?wx_fmt=png

接下来,一步步解析下上面的过程:
1)使用lag函数,得到其前面一个数:
select year as min_year,num,lag(num,1) over(order by year) as pre_numfrom default.a3
2)判断当前数和前面一个数的关系,得到分块最小值。
如果两个数不相等,说明在此处数发生了变化,是一个新的分块的开始,除此之外,如果没有前一个数,说明当前行是第一行,同样作为一个分块的开始。这样,我们可以得到每个分块的开始:
select min_year,num,pre_num
from (select year as min_year,num,lag(num,1) over(order by year) as pre_numfrom default.a3) a
where num!=pre_numor pre_num is null
这里的结果如下:

640?wx_fmt=png

四个分块的开始分别是2014、2017、2019、2022。
3)判断每一行属于哪个分块
我们需要拿第二步得到的结果与原结果使用第二列进行join,然后判断每一行属于哪个分块。决定每一行的所属分块有两个条件,首先该行第一列的值要大于或等于分块的最小值;其次,在所有满足条件的分块最小值中,选择最大的一个,便是该行所在分块的最小值。
所以这里我们首先进行join操作,然后使用row_number()得到了每一行所在的分块:
select year,num,min_yearfrom(select year,base.num as num,min_year,row_number() over(partition by base.year order by min_year desc) as rankfrom (select *from default.a3) baseinner join (select min_year,num,pre_numfrom (select year as min_year,num,lag(num,1) over(order by year) as pre_numfrom default.a3) awhere num!=pre_numor pre_num is null) min_yearon base.num = min_year.numwhere base.year >= min_year.min_year) ccwhere rank = 1order by year
结果如下:

640?wx_fmt=png

4)把分块最小值作为分组键,进行分组排序
好了,这四道题就解析完毕了,抓紧时间去练习一下吧~~
(*本文为 AI大本营转载文章,转载请联系原作者。)

精彩推荐



640?wx_fmt=png

推荐阅读

  • 鸿蒙 OS 的到来,能为我们改变什么?

  • 干货 | OpenCV看这篇就够了,9段代码详解图像变换基本操作

  • 周杰伦的《说好不哭》,20万点评Python来分析

  • 算法人必懂的进阶SQL知识,4道面试常考题

  • 6张拓扑图揭秘中心化交易所的5种行为, 原来中心化比你想象的重要

  • 分布式存储春天已来Storj首登top10; Cardano排名上升; 以太坊比特币活跃地址双下降 | 数据周榜

  • 华为愿出售5G技术渴望对手;苹果将向印度投资10亿美元;华为全联接大会首发计算战略;腾讯自研轻量级物联网操作系统正式开源……

  • TDD 就是个坑

  • 厉害!接班马云的为何是张勇?

640?wx_fmt=png

你点的每个“在看”,我都认真当成了喜欢

相关文章:

007-迅雷定时重启AutoHotkey脚本-20190411

;; 定时重启迅雷.ahk,;;~ 2019年04月11日;#SingleInstance,forceSetWorkingDir,%A_ScriptDir%DetectHiddenWindows,OnSetTitleMatchMode,2#Persistent ;让脚本持久运行(即直到用户关闭或遇到 ExitApp)。#NoEnv;~ #NoTrayIcon Hotkey,^F10,ExitThisApp lo…

关于ExtJS在使用下拉列表框的二级联动获取数据

2019独角兽企业重金招聘Python工程师标准>>> 使用下拉列表框的二级联动获取数据,如果第一个下拉列表框有默认值时,需要设置fireEvent执行select事件 示例: var combo Ext.getCmp("modifyBuildCom"); combo.setValue(re…

C++中std::sort/std::stable_sort/std::partial_sort的区别及使用

某些算法会重排容器中元素的顺序&#xff0c;如std::sort。调用sort会重排输入序列中的元素&#xff0c;使之有序&#xff0c;它默认是利用元素类型的<运算符来实现排序的。也可以重载sort的默认排序&#xff0c;即通过sort的第三个参数&#xff0c;此参数是一个谓词(predic…

阿里云智能 AIoT 首席科学家丁险峰:阿里全面进军IoT这一年 | 问底中国IT技术演进...

作者 | 屠敏受访者 | 丁险峰来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;「忽如一夜春风来&#xff0c;千树万树梨花开。」从概念的流行、至科技巨头的相继入局、再到诸多应用的落地&#xff0c;IoT 的发展终于在万事俱备只欠东风的条件下真正地迎来了属于自己的…

eBCC性能分析最佳实践(1) - 线上lstat, vfs_fstatat 开销高情景分析...

Guide: eBCC性能分析最佳实践&#xff08;0&#xff09; - 开启性能分析新篇章eBCC性能分析最佳实践&#xff08;1&#xff09; - 线上lstat, vfs_fstatat 开销高情景分析eBCC性能分析最佳实践&#xff08;2&#xff09; - 一个简单的eBCC分析网络函数的latency敬请期待...0. I…

spring-data-mongodb必须了解的操作

http://docs.spring.io/spring-data/data-mongo/docs/1.0.0.M5/api/org/springframework/data/mongodb/core/MongoTemplate.html 在线api文档 1关键之识别 KeywordSampleLogical resultGreaterThanfindByAgeGreaterThan(int age){"age" : {"$gt" : age}}Le…

旷视张祥雨:高效轻量级深度模型的研究和实践 | AI ProCon 2019

演讲嘉宾 | 张祥雨&#xff08;旷视研究院主任研究员、基础模型组负责人&#xff09;编辑 | Just出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;基础模型是现代视觉识别系统中一个至关重要的关注点。基础模型的优劣主要从精度、速度或功耗等角度判定&#xff0c;如何…

Python脱产8期 Day02

一 语言分类 机器语言&#xff0c;汇编语言&#xff0c;高级语言&#xff08;编译和解释&#xff09; 二 环境变量 1、配置环境变量不是必须的2、配置环境变量的目的&#xff1a;为终端提供执行环境 三Python代码执行的方式 1交互式&#xff1a;.控制台直接编写运行python代码 …

分别用Eigen和C++(OpenCV)实现图像(矩阵)转置

(1)、标量(scalar)&#xff1a;一个标量就是一个单独的数。(2)、向量(vector)&#xff1a;一个向量是一列数&#xff0c;这些数是有序排列的&#xff0c;通过次序中的索引&#xff0c;可以确定每个单独的数。(3)、矩阵(matrix)&#xff1a;矩阵是一个二维数组&#xff0c;其中的…

Linux基础优化

***************************************************************************************linux系统的优化有很多&#xff0c;我简单阐述下我经常优化的方针&#xff1a;记忆口诀&#xff1a;***********************一清、一精、一增&#xff1b;两优、四设、七其他。*****…

数据集cifar10到Caffe支持的lmdb/leveldb转换的实现

在 http://blog.csdn.net/fengbingchun/article/details/53560637 对数据集cifar10进行过介绍&#xff0c;它是一个普通的物体识别数据集。为了使用Caffe对cifar10数据集进行train&#xff0c;下面实现了将cifar10到lmdb/leveldb的转换实现&#xff1a;#include "funset.h…

计算两个时间的间隔时间是多少

/*** 计算两个时间间隔* param startTime 开始时间* param endTime 结束时间* param type 类型&#xff08;1&#xff1a;相隔小时 2&#xff1a;&#xff09;* return*/public static int compareTime(String startTime, String endTime, int type) {if (endTime nul…

作为西二旗程序员,我是这样学习的.........

作为一名合格的程序员&#xff0c;需要时刻保持对新技术的敏感度&#xff0c;并且要定期更新自己的技能储备&#xff0c;是每个技术人的日常必修课。但要做到这一点&#xff0c;知乎上的网友说最高效的办法竟然是直接跟 BAT 等一线大厂取经。讲真的&#xff0c;BAT大厂的平台是…

2月国内搜索市场:360继续上升 百度下降0.62%

IDC评述网&#xff08;idcps.com&#xff09;03月06日报道&#xff1a;根据CNZZ数据显示&#xff0c;在国内搜索引擎市场中&#xff0c;百度在2014年2月份所占的份额继续被蚕食&#xff0c;环比1月份&#xff0c;下降了0.62%&#xff0c;为60.50%。与此相反&#xff0c;360搜索…

不止于刷榜,三大CV赛事夺冠算法技术的“研”与“用”

&#xff08;由AI科技大本营付费下载自视觉中国&#xff09;整理 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;在 5 个月时间里&#xff08;5月-9月&#xff09;&#xff0c;创新工场旗下人工智能企业创新奇智连续在世界顶级人脸检测竞赛 WIDER …

Ubuntu14.04上编译指定版本的protobuf源码操作步骤

Google Protobuf的介绍可以参考 http://blog.csdn.net/fengbingchun/article/details/49977903 &#xff0c;这里介绍在Ubuntu14.04上编译安装指定版本的protobuf的操作步骤&#xff0c;这里以2.4.1为例&#xff1a;1&#xff0e; Ubuntu14.04上默认安装的是2.5.0&#xff0c;…

Linux下,各种解压缩命令集合

Linux下&#xff0c;各种解压缩命令集合tar xvfj lichuanhua.tar.bz2tar xvfz lichuanhua.tar.gztar xvfz lichuanhua.tgztar xvf lichuanhua.tarunzip lichuanhua.zip.gz解压 1&#xff1a;gunzip FileName.gz解压 2&#xff1a;gzip -d FileName.gz压缩&#xff1a;gzip File…

gtest使用初级指南

之前在 http://blog.csdn.net/fengbingchun/article/details/39667571 中对google的开源库gtest进行过介绍&#xff0c;现在看那篇博文&#xff0c;感觉有些没有说清楚&#xff0c;这里再进行总结下&#xff1a;Google Test是Google的开源C单元测试框架&#xff0c;简称gtest。…

iOS视频流采集概述(AVCaptureSession)

需求&#xff1a;需要采集到视频帧数据从而可以进行一系列处理(如: 裁剪&#xff0c;旋转&#xff0c;美颜&#xff0c;特效....). 所以,必须采集到视频帧数据. 阅读前提: 使用AVFoundation框架采集音视频帧数据GitHub地址(附代码) : iOS视频流采集概述 简书地址 : iOS视频流采…

300秒搞定第一超算1万年的计算量,量子霸权时代已来?

&#xff08;由AI科技大本营付费下载自视觉中国&#xff09;作者 | 马超责编 | 郭芮来源 | CSDN 博客近日&#xff0c;美国航天局&#xff08;NASA&#xff09;发布了一篇名为《Quantum Supremacy Using a Programmable Superconducting Processor》的报道&#xff0c;称谷歌的…

2014-3-6 星期四 [第一天执行分析]

昨日进度&#xff1a; [毛思想]&#xff1a;看测控技术量待定 --> [良]超额完成&#xff0c;昨天基本上把测控看了一大半啦 [汇编]&#xff1a;认真听课&#xff0c;边听边消化自学 --> [中]基本满足&#xff0c;还需要抽时间总结&#xff0c;特别是前面寻址的各种情况…

行列式介绍及Eigen/OpenCV/C++的三种实现

行列式&#xff0c;记作det(A)&#xff0c;是一个将方阵A映射到实数的函数。行列式等于矩阵特征值的乘积。行列式的绝对值可以用来衡量矩阵参与矩阵乘法后空间扩大或者缩小了多少。如果行列式是0&#xff0c;那么空间至少沿着某一维完全收缩了&#xff0c;使其失去了所有的体积…

基于Go的语义解析开源库FMR,“屠榜”模型外的NLP利器

&#xff08;由AI科技大本营付费下载自视觉中国&#xff09;作者 | 刘占亮 一览群智技术副总裁编辑 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;如何合理地表示语言的内在意义&#xff1f;这是自然语言处理业界中长久以来悬而未决的一个命题。在…

【高级数据类型2】- 10. 接口

2019独角兽企业重金招聘Python工程师标准>>> Go语言-接口 在Go语言中&#xff0c;一个接口类型总是代表着某一种类型&#xff08;即所有实现它的类型&#xff09;的行为。一个接口类型的声明通常会包含关键字type、类型名称、关键字interface以及由花括号包裹的若干…

Linux软件包命令

2019独角兽企业重金招聘Python工程师标准>>> dpkg命令&#xff1a; dpkg -i **/**.deb 安装软件 dpkg -x **.deb 解开.deb文件 dpkg -r /-p 删除并清配置 更详细的 用dpkg --help 查询 如下&#xff1a; dpkg -i|--install <.deb 文件的文件名> ... | -R|--re…

Caffe中计算图像均值的实现(cifar10)

在深度学习中&#xff0c;在进行test时经常会减去train数据集的图像均值&#xff0c;这样做的好处是&#xff1a;属于数据预处理中的数据归一化&#xff0c;降低数据间相似性&#xff0c;可以将数值调整到一个合理的范围。以下code是用于计算cifar10中训练集的图像均值&#xf…

阿里云弹性公网IP(EIP)的使用限制

阿里云弹性公网IP&#xff08;EIP&#xff09;是一种可以独立购买和持有的公网IP地址资源&#xff0c;弹性公网IP具有独立购买持有、弹性绑定和配置灵活等优势&#xff0c;但实际使用中弹性公网IP也是有很多限制的&#xff0c;阿里云惠网分享弹性公网IP&#xff08;EIP&#xf…

400名微软员工主动曝光薪资:28万元到228万元不等!

作者 | Dave Gershgorn译者 | 弯月&#xff0c;编辑 | 郭芮来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;【导读】近日&#xff0c;近400名微软员工分享了他们的薪酬&#xff08;从4万美元到32万美元不等&#xff0c;约为28万人民币到228万人民币&#xff09;&am…

Extjs:添加查看全部按钮

var grid new Ext.grid.GridPanel({renderTo:tsllb,title:产品成本列表,selModel:csm,height:350,columns:[csm,{header: "编码", dataIndex: "bm", sortable: true,hidden:true},{header: "产品", dataIndex: "cp", sortable: true},…

练手扎实基本功必备:非结构文本特征提取方法

作者 | Dipanjan (DJ) Sarkar编译 | ronghuaiyang来源 | AI公园&#xff08;ID:AI_Paradise&#xff09;【导读】本文介绍了一些传统但是被验证是非常有用的&#xff0c;现在都还在用的策略&#xff0c;用来对非结构化的文本数据提取特征。介绍在本文中&#xff0c;我们将研究如…