⑴ sql max函数的使用方法
sql max函数的使用方法
在SQL数据库中,最大/最小值函数—MAX/MIN是经常要用到的。下面我给大家带来sql max函数的使用方法,欢迎大家阅读。
sql max函数的使用方法
当需要了解一列中的最大值时,可以使用MAX()函数;同样,当需要了解一列中的最小值时,可以使用MIN()函数。语法如下。
SELECT MAX (column_name) / MIN (column_name)
FROM table_name
说明:列column_name中的数据可以是数值、字符串或是日期时间数据类型。MAX()/MIN()函数将返回与被传递的列同一数据类型的单一值。
实例7 MAX()函数的使用
查询TEACHER表中教师的最大年龄。实例代码:
SELECT MAX (AGE) AS MAXAGE
FROM TEACHER
运行结果如图1示。
图1TEACHER表中教师的最大年龄
然而,在实际应用中得到这个结果并不是特别有用,因为经常想要获得的信息是具有最大年龄的教师的教工号、姓名、性别等信息。
然而SQL不支持如下的SELECT语句。
SELECT TNAME, DNAME, TSEX, MAX (AGE)
FROM TEACHER
因为聚合函数处理的是数据组,在本例中,MAX函数将整个TEACHER表看成一组,而TNAME、DNAME和TSEX的数据都没有进行任何分组,因此SELECT语句没有逻辑意义。同样的道理,下面的.代码也是无效的。
SELECT TNAME, DNAME, TSEX,SAL ,AGE
FROM TEACHER
WHERE AGE=MAX (AGE)
解决这个问题的方法,就是在WHERE子句中使用子查询来返回最大值,然后再基于这个返回的最大值,查询相关信息。
实例8 在WHERE子句中使用子查询返回最大值
查询TEACHER表中年纪最大的教师的教工号、姓名、性别等信息。
实例代码:
SELECT TNAME, DNAME, TSEX, SAL, AGE
FROM TEACHER
WHERE AGE=(SELECT MAX (AGE) FROM TEACHER)
运行结果如图2示。
图2在WHERE子句中使用子查询返回最大值
MAX()和MIN()函数不仅可以作用于数值型数据,也可以作用于字符串或是日期时间数据类型的数据。
实例MAX()函数用于字符型数据
如下面代码:
SELECT MAX (TNAME) AS MAXNAME
FROM TEACHER
运行结果如图3示。
图3在字符串数据类型中使用MAX的结果
可见,对于字符串也可以求其最大值。
说明
对字符型数据的最大值,是按照首字母由A~Z的顺序排列,越往后,其值越大。当然,对于汉字则是按照其全拼拼音排列的,若首字符相同,则比较下一个字符,以此类推。
当然,对与日期时间类型的数据也可以求其最大/最小值,其大小排列就是日期时间的早晚,越早认为其值越小,如下面的实例。
实例 MAX()、MIN()函数用于时间型数据
从COURSE表中查询最早和最晚考试课程的考试时间。其中COURSE表的结构和数据可参见本书6.1节的表6-1。实例代码:
SELECT MIN (CTEST) AS EARLY_DATE,
MAX (CTEST) AS LATE_DATE
FROM COURSE
运行结果如图4示。
图4COURSE表中最早和最晚考试课程的考试时间
可见,返回结果的数据类型与该列定义的数据类型相同。
注意
确定列中的最大值(最小值)时,MAX( )(MIN( ))函数忽略NULL值。但是,如果在该列中,所有行的值都是NULL,则MAX( )/MIN( )函数将返回NULL值。
;⑵ Hive sql及窗口函数
hive函数:
1、根据指定条件返回结果:case when then else end as
2、基本类型转换:CAST()
3、nvl:处理空字段:三个str时,是否为空可以指定返回不同的值
4、sql通配符: https://www.w3school.com.cn/sql/sql_wildcards.asp
5、count(1)与COUNT(*):返回行数
如果表没有主键,那么count(1)比count(*)快;
如果有主键,那么count(主键,联合主键)比count(*)快;
count(1)跟count(主键)一样,只扫描主键。count(*)跟count(非主键)一样,扫描整个表。明显前者更快一些。
性能问题:
1.任何情况下SELECT COUNT(*) FROM tablename是最优选择,(指没有where的情况);
2.尽量减少SELECT COUNT(*) FROM tablename WHERE COL = ‘value’ 这种查询;
3.杜绝SELECT COUNT(COL) FROM tablename WHERE COL2 = ‘value’ 的出现。
count(expression):查询 is_reply=0 的数量: SELECT COUNT(IF(is_reply=0,1,NULL)) count FROM t_iov_help_feedback;
6、distinct与group by
distinct去重所有distinct之后所有的字段,如果有一个字段值不一致就不作为一条
group by是根据某一字段分组,然后查询出该条数据的所需字段,可以搭配 where max(time)或者Row_Number函数使用,求出最大的一条数据
7、使用with 临时表名 as() 的形式,简单的临时表直接嵌套进sql中,复杂的和需要复用的表写到临时表中,关联的时候先找到关联字段,过滤条件最好在临时表中先过滤后关联
处理json的函数:
split(json_array_string(schools), '\\|\\|') AS schools
get_json_object(school, '$.id') AS school_id,
字符串函数:
1、instr(’源字符串’ , ‘目标字符串’ ,’开始位置’,’第几次出现’)
instr(sourceString,destString,start,appearPosition)
1.sourceString代表源字符串; destString代表要从源字符串中查找的子串;
2.start代表查找的开始位置,这个参数可选的,默认为1;
3.appearPosition代表想从源字符中查找出第几次出现的destString,这个参数也是可选的, 默认为1
4.如果start的值为负数,则代表从右往左进行查找,但是位置数据仍然从左向右计算。
5.返回值为:查找到的字符串的位置。如果没有查找到,返回0。
最简单例子: 在abcd中查找a的位置,从第一个字母开始查,查找第一次出现时的位置
select instr(‘abcd’,’a’,1,1) from al; —1
应用于模糊查询:instr(字段名/列名, ‘查找字段’)
select code,name,dept,occupation from staff where instr(code, ‘001’)> 0;
等同于 select code, name, dept, occupation from staff where code like ‘%001%’ ;
应用于判断包含关系:
select ccn,mas_loc from mas_loc where instr(‘FH,FHH,FHM’,ccn)>0;
等同于 select ccn,mas_loc from mas_loc where ccn in (‘FH’,’FHH’,’FHM’);
2、substr(string A,int start,int len)和 substring(string A,int start,int len),用法一样
substr(time,1,8) 表示将time从第1位开始截取,截取的长度为8位
第一种用法:
substr(string A,int start)和 substring(string A,int start),用法一样
功效:返回字符串A从下标start位置到结尾的字符串
第二种用法:
substr(string A,int start,int len)和 substring(string A,int start,int len),用法一样
功效:返回字符串A从下标start位置开始,长度为len的字符串
3、get_json_object(form_data,'$.学生姓名') as student_name
json_tuple 函数的作用:用来解析json字符串中的多个字段
4、split(full_name, '\\.') [5] AS zq; 取的是数组里的第六个
日期(时间)函数:
1、to_date(event_time) 返回日期部分
2、date_sub:返回当前日期的相对时间
当前日期:select curdate()
当前日期前一天:select date_sub(curdate(),interval 1 day)
当前日期后一天:select date_sub(curdate(),interval -1 day)
date_sub(from_unixtime(unix_timestamp(), 'yyyy-MM-dd HH:mm:ss'), 14) 将现在的时间总秒数转为标准格式时间,返回14天之前的时间
时间戳>>>>日期:
from_unixtime(unix_timestamp(), 'yyyy-MM-dd HH:mm:ss') 将现在的时间总秒数转为标准格式时间
from_unixtime(get_json_object(get_json_object(form_data,'$.挽单时间'),'$.$date')/1000) as retain_time
unix_timestamp('2019-08-15 16:40:00','yyyy-MM-dd HH:mm:ss') --1565858400
日期>>>>时间戳:unix_timestamp()
date_format:yyyy-MM-dd HH:mm:ss 时间转格式化时间
select date_format('2019-10-07 13:24:20', 'yyyyMMdd000000')-- 20191007000000select date_format('2019-10-07', 'yyyyMMdd000000')-- 20191007000000
1.日期比较函数: datediff语法: datediff(string enddate,string startdate)
返回值: int
说明: 返回结束日期减去开始日期的天数。
举例: hive> select datediff('2016-12-30','2016-12-29'); 1
2.日期增加函数: date_add语法: date_add(string startdate, intdays)
返回值: string
说明: 返回开始日期startdate增加days天后的日期。
举例: hive>select date_add('2016-12-29',10); 2017-01-08
3.日期减少函数: date_sub语法: date_sub (string startdate,int days)
返回值: string
说明: 返回开始日期startdate减少days天后的日期。
举例: hive>select date_sub('2016-12-29',10); 2016-12-19
4.查询近30天的数据
select * from table where datediff(current_timestamp,create_time)<=30;
create_time 为table里的字段,current_timestamp 返回当前时间 2018-06-01 11:00:00
3、trunc()函数的用法:当前日期的各种第一天,或者对数字进行不四舍五入的截取
日期:
1.select trunc(sysdate) from al --2011-3-18 今天的日期为2011-3-18
2.select trunc(sysdate, 'mm') from al --2011-3-1 返回当月第一天.
上月1号 trunc(add_months(current_date(),-1),'MM')
3.select trunc(sysdate,'yy') from al --2011-1-1 返回当年第一天
4.select trunc(sysdate,'dd') from al --2011-3-18 返回当前年月日
5.select trunc(sysdate,'yyyy') from al --2011-1-1 返回当年第一天
6.select trunc(sysdate,'d') from al --2011-3-13 (星期天)返回当前星期的第一天
7.select trunc(sysdate, 'hh') from al --2011-3-18 14:00:00 当前时间为14:41
8.select trunc(sysdate, 'mi') from al --2011-3-18 14:41:00 TRUNC()函数没有秒的精确
数字:TRUNC(number,num_digits) Number 需要截尾取整的数字。Num_digits 的默认值为 0。TRUNC()函数截取时不进行四舍五入
11.select trunc(123.458,1) from al --123.4
12.select trunc(123.458,-1) from al --120
4、round():四舍五入:
select round(1.455, 2) #结果是:1.46,即四舍五入到十分位,也就是保留两位小数
select round(1.5) #默认四舍五入到个位,结果是:2
select round(255, -1) #结果是:260,即四舍五入到十位,此时个位是5会进位
floor():地板数
ceil()天花板数
5、
6.日期转年函数: year语法: year(string date)
返回值: int
说明: 返回日期中的年。
举例:
hive> select year('2011-12-08 10:03:01') from al;
2011
hive> select year('2012-12-08') fromal;
2012
7.日期转月函数: month语法: month (string date)
返回值: int
说明: 返回日期中的月份。
举例:
hive> select month('2011-12-08 10:03:01') from al;
12
hive> select month('2011-08-08') fromal;
8
8.日期转天函数: day语法: day (string date)
返回值: int
说明: 返回日期中的天。
举例:
hive> select day('2011-12-08 10:03:01') from al;
8
hive> select day('2011-12-24') fromal;
24
9.日期转小时函数: hour语法: hour (string date)
返回值: int
说明: 返回日期中的小时。
举例:
hive> select hour('2011-12-08 10:03:01') from al;
10
10.日期转分钟函数: minute语法: minute (string date)
返回值: int
说明: 返回日期中的分钟。
举例:
hive> select minute('2011-12-08 10:03:01') from al;
3
11.日期转秒函数: second语法: second (string date)
返回值: int
说明: 返回日期中的秒。
举例:
hive> select second('2011-12-08 10:03:01') from al;
1
12.日期转周函数: weekofyear语法: weekofyear (string date)
返回值: int
说明: 返回日期在当前的周数。
举例:
hive> select weekofyear('2011-12-08 10:03:01') from al;
49
查看hive表在hdfs中的位置:show create table 表名;
在hive中hive2hive,hive2hdfs:
HDFS、本地、hive -----> Hive:使用 insert into | overwrite、loaddata local inpath "" into table student;
Hive ----> Hdfs、本地:使用:insert overwrite | local
网站访问量统计:
uv:每用户访问次数
ip:每ip(可能很多人)访问次数
PV:是指页面的浏览次数
VV:是指你访问网站的次数
sql:
基本函数:
count、max、min、sum、avg、like、rlike('2%'、'_2%'、%2%'、'[2]')(java正则)
and、or、not、in
where、group by、having、{ join on 、full join} 、order by(desc降序)
sort by需要与distribut by集合结合使用:
hive (default)> set maprece.job.reces=3; //先设置rece的数量
insert overwrite local directory '/opt/mole/datas/distribute-by'
row format delimited fields terminated by '\t'
先按照部门编号分区,再按照员工编号降序排序。
select * from emp distribute by deptno sort by empno desc;
外部表 create external table if not exists dept
分区表:create table dept_partition ( deptno int, dname string, loc string ) partitioned by ( month string )
load data local inpath '/opt/mole/datas/dept.txt' into table default.dept_partition partition(month='201809');
alter table dept_partition add/drop partition(month='201805') ,partition(month='201804');
多分区联合查询:union
select * from dept_partition2 where month='201809' and day='10';
show partitions dept_partition;
desc formatted dept_partition;
二级分区表:create table dept_partition2 ( deptno int, dname string, loc string ) partitioned by (month string, day string) row format delimited fields terminated by '\t';
分桶抽样查询:分区针对的是数据的存储路径;分桶针对的是数据文件
create table stu_buck(id int, name string) clustered by(id) into 4 bucketsrow format delimited fields terminated by '\t';
设置开启分桶与rece为1:
set hive.enforce.bucketing=true;
set maprece.job.reces=-1;
分桶抽样:select * from stu_bucktablesample(bucket x out of y on id);
抽取,桶数/y,x是从哪个桶开始抽取,y越大 抽样数越少,y与抽样数成反比,x必须小于y
给空字段赋值:
如果员工的comm为NULL,则用-1代替或用其他字段代替 :select nvl(comm,-1) from emp;
case when:如何符合记为1,用于统计、分组统计
select dept_id, sum(case sex when '男' then 1 else 0 end) man , sum(case sex when '女' then 1 else 0 end) woman from emp_sex group by dept_id;
用于组合归类汇总(行转列):UDAF:多转一
concat:拼接查询结果
collect_set(col):去重汇总,产生array类型字段,类似于distinct
select t.base, concat_ws('|',collect_set(t.name)) from (select concat_ws(',',xingzuo,blood_type) base,name from person_info) t group by t.base;
解释:先第一次查询得到一张没有按照(星座血型)分组的表,然后分组,使用collect_set将名字组合成数组,然后使用concat将数组变成字符串
用于拆分数据:(列转行):UDTF:一转多
explode(col):将hive一列中复杂的array或者map结构拆分成多行。
lateral view 侧面显示:用于和UDTF一对多函数搭配使用
用法:lateral view udtf(expression) tablealias as cate
cate:炸开之后的列别名
temptable :临时表表名
解释:用于和split, explode等UDTF一起使用,它能够将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。
开窗函数:
Row_Number,Rank,Dense_Rank over:针对统计查询使用
Row_Number:返回从1开始的序列
Rank:生成分组中的排名序号,会在名词s中留下空位。3 3 5
dense_rank:生成分组中的排名序号,不会在名词中留下空位。3 3 4
over:主要是分组排序,搭配窗口函数使用
结果:
SUM、AVG、MIN、MAX、count
preceding:往前
following:往后
current row:当前行
unbounded:unbounded preceding 从前面的起点, unbounded following:到后面的终点
sum:直接使用sum是总的求和,结合over使用可统计至每一行的结果、总的结果、当前行+之前多少行/之后多少行、当前行到往后所有行的求和。
over(rowsbetween 3/current ) 当前行到往后所有行的求和
ntile:分片,结合over使用,可以给数据分片,返回分片号
使用场景:统计出排名前百分之或n分之一的数据。
lead,lag,FIRST_VALUE,LAST_VALUE
lag与lead函数可以返回上下行的数据
lead(col,n,dafault) 用于统计窗口内往下第n行值
第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为NULL时候,取默认值,如不指定,则为NULL)
LAG(col,n,DEFAULT) 用于统计窗口内往上第n行值
第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往上第n行为NULL时候,取默认值,如不指定,则为NULL)
使用场景:通常用于统计某用户在某个网页上的停留时间
FIRST_VALUE:取分组内排序后,截止到当前行,第一个值
LAST_VALUE:取分组内排序后,截止到当前行,最后一个值
范围内求和: https://blog.csdn.net/happyrocking/article/details/105369558
cume_dist,percent_rank
–CUME_DIST :小于等于当前值的 行数 / 分组内总行数
–比如,统计小于等于当前薪水的人数,占总人数的比例
percent_rank:分组内当前行的RANK值-1/分组内总行数-1
总结:
在Spark中使用spark sql与hql一致,也可以直接使用sparkAPI实现。
HiveSql窗口函数主要应用于求TopN,分组排序TopN、TopN求和,前多少名前百分之几。
与Flink窗口函数不同。
Flink中的窗口是用于将无线数据流切分为有限块处理的手段。
window分类:
CountWindow:按照指定的数据条数生成一个 Window,与时间无关。
TimeWindow:按照时间生成 Window。
1. 滚动窗口(Tumbling Windows):时间对齐,窗口长度固定,不重叠::常用于时间段内的聚合计算
2.滑动窗口(Sliding Windows):时间对齐,窗口长度固定,可以有重叠::适用于一段时间内的统计(某接口最近 5min 的失败率来报警)
3. 会话窗口(Session Windows)无时间对齐,无长度,不重叠::设置session间隔,超过时间间隔则窗口关闭。
⑶ 开窗函数
over在聚合函数中的使用:
一般格式:
聚合函数名(列) over(选项)
over必须与聚合函数或排序函数一起使用,聚合函数为:
sum(),max(),min(),count(),avg()
排序函数为:
rank(),row_number(),dense_rank(),ntile()
over表示把函数当成开窗函数而不是聚合函数,SQL标准允许将所有聚合函数用做开窗函数,使用over关键字来区分这两种用法。
开窗函数不需要使用group by就可以对数据进行分组,就可以同时返回基础行的列和聚合列。
开窗函数sum(*) over(),对于查询结果的每一行都返回所有符合条件的行的条数,over关键字后的括号中还经常添加选项来改变进行聚合运算的窗口范围,如果over关键字后的括号中选项为空,则开窗函数会对结果集中的所有行进行聚合运算。
常用格式:
sum(*) over(partition by A order by B)
partition by:进行分组,得到对应组内的所有求和值
order by:按照B进行排序,得到对应组内的累计求和值(如果B为id,两个id相同,则这两个id返回的sum那一列是相同的聚合值,是累计到最后一个id对应值的和--下面的例子会详细说明)
order by 字段名 rows|range between 边界规则1 and 边界规则2
rows:表示按照行的范围进行范围的定位
range:表示按照取值的范围进行范围的定位
这两种不同的定位方式主要用来处理并列排序的情况(见下面的例子)
边界规则的可取值为:
current row--当前行
n preceding--前n行
unbounded preceding--一直到第一条记录
n following--后n行
unbounded following--一直到最后一条记录
'range/rows between 边界规则1 and 边界规则2':用来定位聚合计算范围,被称为定位框架。
eg:
1、建表
2、插入数据
3、关于partition by
(1)所属城市的人员数-按城市进行分组聚合
(2)显示每一个人员的信息、所属城市的人员数以及同龄人的人数
在同一个SELECT语句中可以同时使用多个开窗函数,而且这些开窗函数并不会相互干扰。
4、关于order by的详解:
(1)查询从第一行到当前行的的工资总和
(2)将上面的row换成range
结果和(1)的区别体现在红框和黄框部分,按照FSalary进行排序,row-按照行的范围进行范围定位,所以每一行后面对应的‘到当前行工资求和’都不一样,都严格的是第一行到当前行的累计和;range-按照取值的范围进行范围定位,虽然定位框架的语法仍然是从第一行到当前行的累计和,但是由于取值的范围:等于2000元的工资有3人,所以计算的累计为从第一条到2000元工资的最后一个人,写在每个2000元工资的人的后面都是7000。
(3)将(2)中的定位框架省略
上述框架是开窗函数中最常用的定位框架,如果是这种框架的话,可以省略上述定位框架部分
得到的结果和(2)的结果一样。
(4)将上面的sum()换成count(),计算工资排名
按照salary进行排序,然后计算从第一行(unbounded preceding)到当前行(current row)的人员的个数,相当于计算人员的的工资水平排名。
Question:
怎么让工资为2000元的排名都为2?--见后面排序函数的rank()和dence_rank()
5、关于over(partition by A order by B)
over在排序函数中的使用:
一般格式:
排序函数(列) over(选项)
排序函数为:
rank(),dense_rank(),row_number(),ntile(),lead(),lag()
1、rank(),dense_rank(),row_number()的区别
rank()与dense_rank()的区别:
两者都是计算一组数值中的排序值,
但是在有并列关系时,dence_rank中相关等级不会跳过,rank则跳过。
rank() 是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内)
dense_rank()是连续排序,有两个第二名时仍然跟着第三名。
row_number():
row_number over(partition by A order by B)
根据A分组,在分组内根据B排序,且得出来的值是每组内部排序后的顺序编号(组内连续的唯一的)
其主要是‘行’的信息,并没有排名。row_number()必须与order by一起使用,
多用于分页查询,比如查询10-100个学生。
2、ntile(x)--平均分区函数
3、lag() over(partition by A order by B)
lead() over(partition by A order by B)
lag和lead中有三个参数,lag('列名',offset,'超出记录窗口时的默认值')
lag和lead可以获取,按一定顺序B排列的当前行的上下相邻若干offset的莫隔行的某个列。
lag()是向前,lead()是向后。
参考 https://www.cnblogs.com/lihaoyang/p/6756956.html
⑷ SQL中的max(sname)是什么意思
max(sname)返回snmae中最大的列值
MAX 函数返回一列中的最大值。NULL 值不包括在计算中。
SQL MAX() 语法
SELECT MAX(column_name) FROM table_name注释:MIN 和 MAX 也可用于文本列,以获得按字母顺序排列的最高或最低值。
⑸ sql查询语句如何写
我的写法是oracle的,如果是其他数据库,自己调整(比如mysql的必须有别名等等)
两个办法
(1)编号和还款日期合并求最大值,然后再查询一次。
select * from table where 编号||还款记录 in (select 编号||max(还款记录) 合并记录 from table group by 编号)
(2)开窗函数,按照还款日期排序,然后求最大的那个。
select 编号,还款日期,金额 from (select rank()over(group by 编号 order by 还款日期 desc) 倒序,编号,还款记录,金额 from table) where 倒序=1
⑹ 在SQL中可以使用MAX函数取两个数中较大的一个数吗 在线等啊
在 SQL中 max 是聚合函数,只能在某列上聚合求最大值,不能像在.net里头的max(a,b)方法来求最大值。
可以使用 case when .
select case when a> b then a else b end as max_value from table
⑺ 一个sql语句,其中max怎么解释呢
MAX() 函数
MAX() 函数返回指定列的最大值。
SQL MAX() 语法
⑻ 【SQL】SQL语句中MAX()函数能有几个参数
--MAX(字段一,字段二)
改为
MAX(字段一)+max(字段二)--字符时直接用+,有数字时要转换后再+