b视频:戴戴戴师兄(BV1ZM4y1u7uF)课程2.0 SQL相关
学习内容:基础语法/常见函数/高级语句-窗口函数
标准语法
select 字段名
from 表名
[where 表达式]
[group by 字段名]
[having 表达式]
[order by 字段名 asc/desc]
[limit 位置偏移量,行数]
原表数据部分示例
world
nobel
1.基础语法
(1)having
限定分组聚合后的查询行必须满足的条件
对group by分组后的数据进行筛选
例:查询总人口数量至少为1亿的大洲
select continent,sum(population) from world
group by continent
having sum(population)>=100000000
where只能进行逻辑运算和比较运算,不能进行聚合运算
having只能用聚合函数和group by作为分组依据的字段
聚合前的字段用where,聚合数值/后用having
例:查询总人口数至少为3亿的大洲和其平均gdp,其中只有gdp高于200亿且人口数大于6000万或者gdp低于80亿且首都中含有三个a的国家的计入计算,最后按国家数从大到小排序,只显示第一行
select continent,avg(gdp) from world
where (gdp>=20000000000 and population>=60000000) or
(gdp<=8000000000 and capital like'%a%a%a')
group by continent
having sum(population)
order by count(name) desc
limit 1,1
例:查询人均gdp大于3000的大洲及其人口数,仅gdp在200亿和300亿之间的国家计入计算
select continent,sum(population),sum(gdp)/sum(population) 人均gdp from world
where gdp between 20000000000 and 30000000000
group by continent
having sum(gdp)/sum(population)>3000
(2)部分常见函数
1)round(x,y)
四舍五入函数,精确到小数点后y位
y为负值时,保留小数点左边相应的位数为0,不进行四舍五入
例:round(3.16,1)返回3.1;round(14.25,-1)返回10
2)concat(s1,s2,…)
连接字符串函数
任一参数为null,则返回null
例:concat(’my’,’ ’,’sql’)返回my sql;concat(’my’,null,’sql’)返回null
3)replace(s,s1,s2)
使用字符串s2代替s中所有的s1
例:replace(’mySQLmySQL’,’SQL’,’sql’)返回mysqlmysql
4)left(s,n)/right(s,n)/substring(s,n,len)
left:返回字符串s最左边的n个字符
right:返回字符串s最右边n个字符
substring返回字符串s从第n个字符起取长度为len的子字符串,n也可以为负值,则从倒数第n个字符起取长度为len的子字符串,没有len值则取从第n个字符到最后一位
例:substring(’abcdefg’,-2,3)返回fg
5)cast(x as type)
将一个类型的x值转换为另一个类型的值
type参数可以填写char(n)/data/time(小时:分钟:秒)/datetime(日期+时间)/decimal(m,d)m是数字的最大数,d是小数点右侧数字的数目
6)日期时间函数
获取年月日函数:year(date)/month(date)/day(date)
对指定起始时间进行加减操作:date_add(date,interval expr type)/date_sub(date,interval exp type)
例:date_add('2021-08-0323:59:59', interval 1 second)返回2021-08-04 24:00:00
计算两个日期之间间隔的天数:datediff(date1,date2)
注:是返回天数,天数
将日期和时间格式化:date_format(date,format)
例:date_format(‘2018-06-0116:23:12’,’%b %d %Y %h:%i %p')
返回Jun 01 201804:23 PM
例:date_format('2018-06-01 16:23:12',%Y/%d/%m')返回2018/01/06
7)条件判断函数
if(expr,v1,v2)
case when
例:case 2 when 1 then ‘one’ when 2 then ‘two’ else ‘more’ end 返回two
当case2对应1返回one,对应2返回two,其余返回more
8)练习
原表covid
部分数据示例
例:case when的运用
select
recovered 累计治愈人数
,case when recovered = 1 then 'one' when recovered > 1 then'more' else 'o' end
from covid
where recovered > 0
例:year/month/day
select
whn 更新时间,year (whn)年,month (whn)月,day (whn)日 from covid
where recovered > 0
例:round和concat嵌套得到百分比数据
select confirmed,deaths,recovered
,recovered/confirmed
,concat(round((recovered/confirmed)*100,2),'%') 治愈率 from covid
where recovered/confirmed > 0.3
例:查询国家名称及其首都名称都以相同的字母开头的国家及其首都,且不能包括国家名称和首都名称完全相同的情况
select name,capital from world
where left(name,1)=left(capital,1) and name!=capital
例:查询首都和名称,其中首都是需是国家名称的扩展
select name,capital from world
where capital like concat('%',name,'%') and capital!=name
over([partition by 字段名][order by字段名asc|desc])
over()中两个子句为可选项,partition by指定分区依据(若没有,则为对整个表进行排序),order by指定排序依据
rank()over()/dense_rank()over()/row_number()over()
例:查询每一年S14000021选区中所有候选人所在的团体(party)和得票数(votes),并对每一年中的所有候选人根据选票数的高低赋予名次,选票数量最高则为1,第二名为2,后续以此类推,最后根据团体(party)和年份(yr)排序
select yr,party,votes,rank()over(partition by yr order by votes desc) posn
from ge
where constituency='S14000021'
order by party,yr
窗口函数只能写在select语句中
窗口函数不受order by和limit影响
运行顺序:
lag(字段名,偏移量[,默认值])over()/lead(字段名,偏移量[,默认值])over()
lag 向上偏移;lead 向下偏移
例:查询法国和德国1月每天新增确诊人数,最后显示国家名、标准日期(2020-01-27)、当天截至时间累计确诊人数、昨天截至时间累计确诊人数、每天新增确诊人数,按照截至时间排序
select name,whn,
date_format(whn,'%y-%m-%d') date
,confirmed 当天截至时间累计确诊人数
,lag(confirmed,1)over(partition by name order by whn) 昨天截止时间累计确诊人数
,(confirmed-lag(confirmed,1)over(partition by name order by whn)) 每天新增确诊人数
from covid
where name in('France','Germany') and month(whn)=1
order by whn
其中:
lag(confirmed,1)over(partition by name order by whn)
over(partition by name order by whn)指按name分区按whn排序
lag(confirmed,1)指查询confirmed对应的列的上1列
先进行了日期排序,前一列则为前一天,这样就取得了昨天截至时间累计确诊人数
例:查询2017年选区为’S14000024’的所有候选人所在团体(party)和其选票数(votes)、还有候选人得票数在选区内对应的排名;结果按团队party排序
select concat(firstName,lastName) 候选人,party,votes
,rank()over(partition by constituency order by votes desc) posn
from ge
where constituency like'S14000024' and yr=2017
order by party
例:查询截至时间为2020年4月20日的国家名、确诊人数排名、死亡人数、死亡人数排名,按照确诊人数降序排名
select name,rank()over(order by confirmed) 确诊人数排名
,deaths 死亡人数
,rank()over(order by deaths) 死亡人数排名
from covid
where whn='2020-4-20'
order by confirmed desc
例:查询意大利每周新增确诊数(显示每周一的数值weekday(whn)=0),最后显示国家名、标准日期(2020-01-27)、每周新增人数,最后按照截至时间排序
select name 国家名
,date_format(whn,'%y-%m-%d') 标准日期
,(confirmed-lag(confirmed,1)over(partition by name order by whn)) 每周新增人数
from covid
where name='Italy' and weekday(whn)=0
order by whn