0. SQL细节要点
Posted Mrs.King_UP
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0. SQL细节要点相关的知识,希望对你有一定的参考价值。
语法结构:select->from->where->group by->having->order by->limit
运行顺序:from->where->group by->having->order by->limit->select
-
like用于where中,进行字符串匹配,%匹配0、1、多个字符 ,_表示一个占位符
-
in 类似于多个or,筛选出字段值介于()之中
-
between v1 and v2 字段值介于两个值之间,且包含两个值(not between v1 and v2不介于两者之间)
-
order by对结果集按照某个字段进行排序,默认asc升序,desc为降序
-
create table 表名(
字段值 字段数据类型 约束
)
这里的约束可能是主键约束primary key、非空约束 not null, 唯一值约束unique -
insert into 表名(字段1,字段2,。。。) values(值1,值2,。。。)
如果插入的值的顺序和表中字段的顺序一致,表名后的字段顺序可以去掉;如果只插入部分字段or插入值的顺序和表中定义的字段顺序不一致,则不可省略字段 -
update 表名 set 字段值1=值1,字段值2=值2 where 条件
用于更新表中的记录,where条件用于指明更新那一条记录,如果不加where,则更新所有记录的字段值 -
delete from 表名 where 条件
删除表中的记录,where条件指明删除的某条记录 -
create index in_name on employees(name);
创建索引,提高访问速度 -
视图是基于SQL语句结果集的可视化表,修改视图,同时底层的表中的数据也会被修改
create view 视图表 as select 字段名 from 表名 where 条件; -
null的判断通过is null 或者is not null,不能用=,!=
-
为表名和字段名使用as起别名,as可以省略
-
join基于两个表之间的共同字段建立连接的一种方式
内连接:列出两个表中都存在的记录
左连接:即使没有匹配也列出左表中的所有记录
右连接:即使没有匹配也列出右表中的所有记录
select 字段名 from 表1 join 表2 on 表1.字段1=表2.字段2 where子句
(on后可以跟多个连接条件,用and连接) -
order by
select winner,subject
from nobel
where yr=1984
order by subject in(‘chemistry’,‘physics’), subject,winner; -
limit限制最后展示出的行数,写在最后
(取前3个)
order by area asc
limit 3
(取第4到第7)
order by area asc
limit 3,4(limit x,n从第x+1行开始返回n行),跳过3条数据取出4条
limit 1 offset 2 从第2条数据(不包括)开始,取出1条数据 -
以下的两种方式均表示取2,3,4三条条数据。
1.select* from test LIMIT 1,3;
当limit后面跟两个参数的时候,第一个数表示要跳过的数量,后一位表示要取的数量。2.select * from test LIMIT 3 OFFSET 1;(在mysql 5以后支持这种写法)
当 limit和offset组合使用的时候,limit后面只能有一个参数,表示要取的的数量,offset表示要跳过的数量 。 -
聚合函数
max()、avg()、min()、sum()
count(*)计算行数;count(字段名)计算非NULL行数 -
group by 字段名
先按照字段名分组(此时对字段名去重);然后对表按照字段名分区;分区之后,根据聚合函数聚合相应的列;填充到分组之后
continents count(name)
19.常见函数
-
数学函数:
round(x,y) x为数值,y为小数点后保留多少位 -
字符串函数:
concat(s1,s2,…)将s1和s2字符串合并
replace(s,s1,s2)将字符串s中的s1字符串替换为s2字符串
left(s,n)从左侧截取n个字符串
right(s,n)从右侧截取n个字符串
substring(s,n,m)从n开始,返回包含n的m个值(字符串首个字符的索引从1开始;或者倒数第一个字符索引为-1)
substring_index(str,delim,count):str为要处理的字符串,delim为分隔符;count计数;count为指定某一个之前的字符串如 str=www.wiki.com
则 substring_index(str,‘.’,1) 处理的结果是:www
substring_index(str,‘.’,2) 得到的结果是:www.wiki
substring_index(str,‘.’,-2) 得到的结果为:wikibt.com -
数据类型转换函数:
cast(x as type) 将x转换为type类型,type可以为char(n)、date、time等 -
日期函数
year(date)、month(date)、day(date):从date中分别截取年月日
date_add(‘2021-08-03 23:59:59’,interval 1 second)对时间进行加法操作
date_sub(date,interval expr type)对时间进行减法操作,type可以为second、minute、hour、day、month、year
datediff(date1,date2)计算两个日期的相隔天数
date_format(date,format)将日期和时间格式化,format为%Y,%D -
条件判断函数
if (1<2,‘True’,‘False’),if(expr,v1,v2)表达式为真返回v1,表达式为假返回v2case expr when v1 then r1 when v2 then r2 else rn end
当expr=v1时,返回r1,当expr=v2时,返回值r2,当两者都不是时,返回值rn,结束;
case 2 when 1 then “one” when 2 then “two” else “more” endcase when v1 then r1 [when v2 then r2] [else rn] end
case when 1<0 then ‘T’ else ‘F’ end
判断1<0,如果为真,返回T,如果为假,返回F
窗口函数
- 语法:
rank() over(partition by 字段名1 order by 字段名2 desc/asc)as pron
- 按照字段名1进行分区;在每一个分区内部按照字段名2进行降序/升序;之后为分区内排序后的记录添加次序并命名为pron
-
专用窗口函数:rank()、dense_rank()、row_number()
- rank():跳跃式排序,
99、99、90、89排序结果为1,1,3,4 - dense_rank():并列连续排序,
99、99、90、89排序结果为1,1,2,3 - row_number():连续性排序,
99、99、90、89排序结果为1,2,3,4
- rank():跳跃式排序,
-
偏移分析窗口函数:lag()、lead()
-
lag():向上取数据。
confirmed-lag(confirmed,1) over(partition by name order by date desc) 按照国家(name)进行分区,再对分区内按照日期(date)降序排序,然后取前一天确诊人数(lag......),当日的确诊人数(confirmed)与前一天确诊人数相减,得到新增人数
-
lead():向下取数据
-
-
注意
- 窗口函数只能用在select语句中
partition by
可以没有,就是对整个表格进行order by
排序;- 窗口函数over中的order by子句不会影响最终结果的排序,只能用来决定窗口函数按照何种顺序排序
-
聚合函数在窗口函数的应用:计算的是累积到当前行的所有的数据的聚合
sum(sale_price) over(order by product_id) as current_sum 1. 按照product_id升序排序,之后计算sale_price的和,命名为current_sum 2. 假如按照product_id排序后,sale_price值的顺序为1000、500、4000、3000,那么,SQL语句的执行结果为1000,100+500,1000+500+4000;1000+500+4000+3000 3. avg()计算当前所在行及之前所有行的均值
-
计算移动平均
rows 2 preceding
- preceding 截止到之前n行,加上自身行
- following 截止到之后n行,加上自身行
- between 1 preceding and 1 following “之前1行”+“之后1行”+“自身”
avg(sale_price) over(order by product_id rows 2 preceding) as moving_avg
- 按照product_id排序后,sale_price值的顺序为1000,500,4000,3000,6800
- 计算当前行和之前2行的平均值,结果为(1000)/1,(1000+500)/2,(1000+500+4000)/3,(500+4000+3000)/3,(4000+3000+6800)/3
avg(sale_price) over(order by product_id rows between 1 preceding and 1 following) as moving_avg
- 按照product_id排序后,sale_price值的顺序为1000,500,4000,3000
- 计算当前行、之前1行和之后1行的平均值,结果为(1000+500)/2,(1000+500+4000)/3,(500+4000+3000)/3,(4000+3000+6800)/3
-
partition by h和group by能同时存在吗?
group by 字段1,字段2与group by 字段2,字段1运行出的结果为什么不一样 -
窗口函数:只能用在select语句中
-
偏移分析窗口函数
-
lag()向上取数据
lag(字段名1,num) over(partition by 字段名2 order by 字段名3 desc/asc)
根据字段名2进行分区;分区内按照字段名3进行排序;然后取当前行的上num行的字段名1的值字段名1-lag(字段名1,num) over(partition by 字段名2 order by 字段名3)
confirmed-lag(confirmed,1) over(partition by name order by date desc)
按照国家(name)进行分区,再对分区内按照日期(date)降序排序,然后取前一天确诊人数(confirmed);当日的确诊人数(confirmed)与前一天确诊人数相减,得到新增人数- lead()向下取数据
10.计算移动平均
preceding
weekday(date)取星期,返回值为0-6,对应星期一到星期日
dayofweek(date)取星期,返回值为1-7s,对应星期一到星期日
经典题目:
select name,date_format(whn,'%Y-%m-%d'),confirmed-lag(confirmed,1) over(order by whn)
from covid
where name='Italy' and weekday(whn)=0
order by whn desc;
以上是关于0. SQL细节要点的主要内容,如果未能解决你的问题,请参考以下文章
2023-01-11:体育馆的人流量。编写一个 SQL 查询以找出每行的人数大于或等于 100 且 id 连续的三行或更多行记录。返回按 visit_date 升序排列 的结果表。 DROP TAB