牛客网SQL篇刷题心得
题目链接:牛客网SQL篇
-
排序的名次:可以通过select来进行实现,即定义一个变量,从而来实现每次累加:
select @t_rank:=0
,通过这种可以实现名次不会因为分数相同而重复的那种;对应的因为分数相同而导致名次相同的也可以通过这个来实现,即通过两个变量,一个来存储名次,一个来存储分数(来实现分数相同,为一样的名次),具体的写法:select grade, case when @mid=grade then @cnt when @mid:=grade then @cnt:=@cnt+1 end t_rank from grades,(select @cnt:=0,@mid:=null) r order by grade desc;
这样即可实现,注意
:=
和=
的区别但是在MySQL8.0中增加了窗口函数,可以便捷解决上述问题:
row_number()
dense_rank()
rank()
第一个即为普通排序;第二个即为分数相同的排序,无间隔;第三个即为分数相同的排序,但是存在间隔
用法:
dense_rank() over(order by xxxxx)
其余的用法与之类似 -
相关累加问题:即当前字段加上前面的字段的数据的和
- 同样也可以采取define变量来进行解决,但是这样总是会出一些莫名的错误(不是答案不正确)
- 可以采取表连接的方法来做,用一张表做主表,一张作为辅助表,利用一些非等值关系即可实现
- 可以利用开窗口函数:
sum(累加的字段) over(order by xxxxxx)
这种方法很简单
-
alter创建索引:
- 主键:
alter table table_name add primary key (column_name);
- 唯一:
alter table table_name add unique index_name (column_name);
- alter创建多个索引:
alter table table_name add .......,add.......;
- 主键:
-
强制使用索引:
force index(index_name)
,通常出现在from表名后面 -
在已创建表中添加字段:
alter table table_name add column 后面和create创建表一样;
-
replace(A,B,C):意为将a中所用的b字符串用c来代替
-
已创建的表添加外键约束:
alter table table_name add constraint foreign key (字段) references 表名(字段名);
,此处注意括号 -
在使用update更新数据的同时,如若被更新的数据是是受限于另一张表的某一个字段,那么可以使用
in
关键字来实现,in后面可以添加一个字段的数据 -
修改表名:
alter table table_name rename to/as new_table_name;
-
in
和exists
的区别:in
:in是查询是否和子查询或者已经存在的记录相匹配;先执行子查询,然后和外表构成一个笛卡尔积,来进行相互匹配。in只会查询一次exists
:exists是查询是否存在该条记录,其不会关注查询的字段,只关心是否存在该字段。首先遍历外表,然后和内表进行相互匹配,如若存在,就将该记录添加到结果集中去;通常在子查询中都会存在两张表,只存在一张表是会出错的
-
查询一个字段中某一个字符串出现的此时:
(length(column_name)-length(replace(column_name,'xxx','')))/单个字符串的长度;
-
查看MySQL中每一个分组的组内的记录的排名,可以使用开窗口函数,就是排序那几个,只需要在over后面添加一个
partition by 分组字段
即可,partition by后面通常也得连用order by -
MySQL中返回月份:
month()
-
如若要将分组中的所有数据连接起来,使用
group_concat(需要连接的字段,'x')
,x通常是连接的标点,通常是,
;这个函数同样需要配合group by来进行使用 -
MySQL中3中插入方式:
insert into
:表示插入数据,database会检查primary key,当插入的数据重复时,就会报错replace into
:表示插入和替换数据,需求表中 存在primary key or unique时,如果database已经存在该记录,就会替换掉该数据;如若没有,就是单纯的插入insert ignore into
:表示如若插入的数据出现重复,就会忽视当前的新数据,(表中存在primary key or unique)
-
在删除数据的同时,不能够同时查找,需要使用中间表
-
触发器:由事件来触发,只能创建在永久表中,不能够创建在视图or临时表中,
格式:
create trigger trigger_name trigger_time trigger_event on table_name for each row trigger_body;
trigger_time:触发时间,after or before
trigger_event:触发事件,insert update delete
trigger_body:触发主体,可以结合begin…end复合语句来使用,因为触发的主体也是SQL语句,同样需要
;
,可以使用old和new来引用触发器中发生的记录内容- old:表示delete和update,删除或者更新之前的数据
- new:表示update和insert,更新或者插入的新数据
具体用法
old.column_name