一、回忆group 查询
group查询便是分组查询,为什么要分组查询?因为咱们想按某个维度进行核算。下面来看个图:
比方说,我想知道:每天Java3y这个大众号的点击量是多少。按咱们人工而言,思路很简略:把相同的天数以及大众号称号为Java3y的数据找出来,再将每个点击量相加,就得出了成果了。
用上SQL咱们或许会这样写:
select name,time,sum(pv) as pv
from xxx_table
where name = 'Java3y' group by name,time
1.1 group 查询或许存在的误解
记住有一天,有个群友在群上问了一个问题:
A8站源码交易平台其实他的需求很简略:检索出数据分组后时刻最高的记载。但他是这样干的:
把先依照时刻 order by
对order by后的记载进行分组
示例图:
1.2 形成这个误解的或许原因
有的东西能够支撑这种的写法:
select * from xxx_table group by name
1
这种写法没有被制止,并能够得出成果,比方得到的成果是:
Java4y 20 7月15号
Java3y 30 7月15号
这种写法其实是不合理的,要知道的是:运用group by分组核算之后,咱们的select 后边只能跟着group by 的字段,或者是聚合函数。
因为,咱们对数据进行了分组查询,数据的散布状况,咱们是不关心的。
记住:先分组,后核算(先把数据归类后,再对相同的数据进行核算)
1.3 group查询最常用的SQL
去重是咱们常常会遇到的问题,打个比方说,因为各种原因(不管是事务上仍是说是脏数据),现在我有两条重复的数据(除了ID,其他的字段都是相同的):
我这边只期望留下某一条记载作为查询成果就好了,咱们能够写下以下的SQL:
select * from user where id in(
select min(id) from user where name = 'Java3y' and pv = 20 and time='7-25' group by name,pv,time;
)
上面这条SQL是十分十分有用的,除了我说的去重以外,其实咱们能够再”考虑“一下:
A8站源码交易平台上面现已说了,运用group by分组核算之后,咱们的select 后边只能跟着group by 的字段,或者是聚合函数。
许多时分咱们group by了今后,还想要查询成果中包括group by之外的字段(一般状况下,咱们都不或许将group by 包括一切的字段),咱们就能够上面那样,将查询后的成果作为子查询,放在外部查询的where 子句后,这样外部查询是能够select 出其他字段的。
(SQL写得比较少的朋友或许没什么感受啊,但我期望上面那种写法咱们能够记住,今后必定会遇到相似的状况的)
二、回忆join查询
join查询不知道咱们在刚学的时分是怎样了解的,横竖我最初如同就挺模模糊糊的。我觉得join查询能够简略了解成这样:我想要的查询成果,一张表搞不掂,那我就join另一张表
比方说,现在我有两张的表:

现在我想知道在7月25号时:每个大众号的点击量、大众号称号、号主称号、大众号的创立日期
明显,咱们会发现一张表搞不掂啊,某些数据要依赖于另一张表才能把数据"完好"展现出来A8站源码交易平台
那join其实便是把两张表合起来的一个操作:
两张表兼并起来今后咱们就会发现,这张“大表”就含有这两张表的一切字段啦,那我想要什么都有了!
值得注意的是:在join的时分,会发生笛卡尔积(至于什么是笛卡尔积我这儿就不说了,横竖咱们要记住的是join表时必定要写相关条件去除笛卡尔积)
别的,left join和right join也是咱们常常用到,假如咱们单纯写join关键字,那会被当成是inner join 。下面我简略解释一下:
上面说了,在join的时分必定要写相关条件,假如是inner join的话,只要契合相关条件的数据才会存在最大表中
假如是left join的话,即使相关条件不契合,左面表的数据必定会存在大表中
假如是right join的话,即使相关条件不契合,右边表的数据必定会存在大表中
看下面的图:
此刻咱们的两张表相关的条件是“大众号” :假如是inner join,那么最终咱们的表只要两条记载。假如是left join ,那么最终咱们的表有三条数据。假如是right join,那么咱们最终的表只要两条数据
三、回忆case when A8站源码交易平台
SQL中的case when then else end用法其实跟咱们程序语言中的if-else很是相似,在写SQL的时分也常常会用到。
我用得比较多的语法如下:
CASE WHEN sex = '1' THEN '男'
WHEN sex = '2' THEN '女'
ELSE '其他' END
hen后边能够跟多个表达式,比方说:
CASE WHEN sex = '1' and name ='Java3y' THEN '男'
WHEN sex = '2' and name ='Java4y' THEN '女'
ELSE '其他' END
假如要为case when表达式取别号,在end 关键字后边直接加就好了
更多用法概况参阅:
https://www.cnblogs.com/prefect/p/5746624.html
四、一些常用的函数
4.1 hive和presto解析json
我这边会有这种状况:将json数据存到MySQL上。我去网上搜了一下以及问了搭档,为什么要将json存到MySQL的字段上时,他们的答复都差不多:
在MySQL存json数据,这样便利扩展啊。假如那些字段不需求用到索引,改动比较频频,你又不想改动表的结构,那能够存json。
ps:在MySQL 5.7版别今后支撑json类型
参阅资料:
https://cloud.tencent.com/developer/article/1004449
https://www.zhihu.com/question/324674084/answer/685522547
我这边做报表一般来hive或presto上搞的,所以解析json的也是在那上面。
hive解析json函数:
get_json_object(param1,'$.param2')
-- 假如是数组
get_json_object(xjson,'$.[0].param2')
presto 对json的处理函数:
-- 数组 (去除第index个json)
json_array_get(xjson,index)
-- 单个jsoin目标
json_extract(xjson,'$.param2')
参阅资料:
https://www.cnblogs.com/drjava/p/10536922.html
4.2 时刻函数
昨日/近7天/本月依照这种目标来查询也是十分常见的:
昨日
SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时刻字段名) <= 1
7天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(时刻字段名)
近30天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(时刻字段名)
本月
SELECT * FROM 表名 WHERE DATE_FORMAT( 时刻字段名, '%Y%m' ) = DATE_FORMAT( CURDATE( ) , '%Y%m' )
上一月
SELECT * FROM 表名 WHERE PERIOD_DIFF( date_format( now( ) , '%Y%m' ) , date_format( 时刻字段名, '%Y%m' ) ) =1
在presto中运用时刻格局,需求清晰写出关键字timestamp,比方:
select supplier,count(id)
from xxx_table
where sendtime >= timestamp '2019-06-01'
参阅资料:
https://blog.csdn.net/cool_easy/article/details/50880949
4.3 其他常用的函数
这儿我简略收拾一下我最近用过函数:
length --核算字符串长度
concat --衔接两个字符串
substring -- 截取字符串
count -- 核算数量
max -- 最大
min -- 最小
sum -- 算计
floor/ceil --...数学函数
A8站源码交易平台再来共享一下最近遇到的一个需求,现在有的数据如下:
【Java3y简略】高兴学习
【Java3y简略】高兴学习渣渣
【Java3y通俗易懂】简略学
【Java3y通俗易懂】简略学芭芭拉
【Java3y和蔼可亲】无聊学
【Java3y初学者】单调学
【Java3y初学者】单调学呱呱
【Java3y大数据】欣喜学
【Java3y学习】巴拉巴拉学
【Java3y学习】巴拉巴拉学哈哈
【Java3y好】雨女无瓜学
现在我核算出【】括号里面呈现的频次,比方说:Java3y通俗易懂呈现的频次是多少。其时一直都没想到好的思路,都快要搜“SQL 正则表达式 快速入门”了,请教了一下搭档,搭档很快就写出来了:
select substring_index(left(title , INSTR(title , '】') -1 ) , '【',-1)
FROM `xxx_table`
A8站源码交易平台 哇~,