该笔记总结了:建表的七大约束、三种删除语句区别、修改表小结、解决only_full_group_by报错
这一块46道题查缺补漏了我个人很多知识盲区~ 感觉像回到了学生时代通过刷题找到不会的知识点,每次遇到不会的题 首先庆幸一下还好不是在高考上才发现的,再去找一些同类型的题目,通过刷题巩固知识点,加深记忆!~
第三板块
SQL1-3 插入记录
复制旧表部分内容带新表:
insert into 新表(列1,列2,...) select 列1,列2,... from 旧表 where 筛选条件;
insert into
exam_record_before_2021(uid,exam_id,start_time,submit_time,score)
select uid,exam_id,start_time,submit_time,score
from exam_record where year(start_time)<2021 and score is not null; #sql2
知识点小结:
(一)建表约束
1、主键约束
使某个字段不重复且不得为空,确保表内所有数据的唯一性。
create table 表名(
id int primary key,
name varchar(20));
2、联合约束
联合主键中的每个字段都不能为空,并且加起来不能和已设置的联合主键重复。
create table 表名(
id int ,
name varchar(20) ,
primary key(id,name) );
3、自增约束
自增约束的主键由系统自动递增分配。
create table 表名(
id int primary key auto_increment,
name varchar(20) );
4、唯一约束
create table 表名(
id int ,
name varchar(20) ,
unique (name) );
5、非空约束
约束某个字段不能为空
create table 表名(
id int ,
name varchar(20) not null );
6、默认约束
约束某个字段的默认值
create table 表名(
id int ,
name varchar(20),
age int default 10 );
7、外键约束
(1) 主表(父表)classes 中没有的数据值,在副表(子表)students 中,是不可以使用的;
(2) 主表中的记录被副表引用时,主表不可以被删除。
SQL7 delete 中limit限制
delete from exam_record where submit_time is null
or date_sub(submit_time,interval 5 minute)<start_time
order by start_time asc limit 3;
#limit 0,3 就通过不了..
评论区解答:delete 是支持 limit 关键字的,但仅支持单个参数
在这道题还学到了一个有用的函数:
timestampdiff (minute, start_time, submit_time) < 5
当然了,date_sub或date_add也是好理解的~
SQL8 删除语句
(二)drop table, truncate table, delete table 三种删除语句的区别
1.drop table 清除数据并且销毁表,是一种数据库定义语言(DDL Data Definition Language), 执行后不能撤销,被删除表格的关系,索引,权限等等都会被永久删除。
2.truncate table 只清除数据,保留表结构,列,权限,索引,视图,关系等等,相当于清零数据,是一种数据库定义语言(DDL Data Definition Language),执行后不能撤销。
3.delete table 删除(符合某些条件的)数据,是一种数据操纵语言(DML Data Manipulation Language),执行后通过事务回滚可以撤销。
delete vs truncate
1.delete 可以加where 条件,truncate 不能加
2.truncate删除,效率高一些
3.假如要删除的表中有自增长列,如果用delete 删除后,再插入数据,自增长列的值从断点开始,而truncate删除后,再插入数据,自增长列的值从1开始
4.truncate删除后没有返回值,delete 删除有返回值
5.truncate 删除后不能回滚,delete 删除可以回滚
SQL9 comment用法:添加字段注释
create table user_info_vip(
id int primary key auto_increment comment '自增ID',
uid int unique not null comment '用户ID',
nick_name varchar(64) comment '昵称',
achievement int default 0 comment '成就值',
level int comment '用户等级',
job varchar(32) comment '职业方向',
register_time datetime default current_timestamp comment '注册时间'
)default charset = UTF8 ;
comment 属性用来添加字段注释
SQL10 alter table 表名 add|modify|drop|change column 字段名 【字段类型】
alter table user_info add column school varchar(15) after level;
alter table user_info change column job profession varchar(10);
alter table user_info modify column achievement int(11) default 0;
知识点小结:
语法:alter table 表名 add|modify|drop|change column 字段名 【字段类型】;
①修改字段名
alter table 表 change column 原列名 现列名 char|int..;
②修改表名
alter table 原表名 rename [TO] 新表明;
③修改字段类型和列级约束
alter table 表 modify column 列名 date|char|int.. ;
④添加字段
alter table 表 add column 列名 varchar(20) first;
⑤删除字段
alter table 表 drop column 列名;
注:
1.默认添加一行列的语句是表示在所有列之后添加
2.如果想在指定列后面添加则要使用after xxx(指定列名)
3.如果是在最开始添加,则在最后使用first即可
SQL18 解决only_full_group_by报错
select date_format(submit_time,'%Y%m') as submit_month,
count(submit_time) as month_q_cnt,
any_value(round(count(submit_time)/day(last_day(submit_time)),3)) as avg_day_q_cnt
from practice_record where year(submit_time)=2021
group by date_format(submit_time,'%Y%m')
union
select '2021汇总' as submit_month,
count(*) as month_q_cnt,
any_value(round(count(*)/31,3)) as avg_day_q_cnt
from practice_record
where year(submit_time)=2021
order by submit_month;
①关于解决最新的SQL版本中ONLY_FULL_GROUP_BY报错的办法:
ONLY_FULL_GROUP_BY的语义就是确定select 中的所有列的值要么是来自于聚合函数(sum、avg、max等)的结果,要么是来自于group by list中的表达式的值。MySQL提供了any_value()函数来抑制ONLY_FULL_GROUP_BY值被拒绝。
所以只需要在非group by的列上加any_value()就可以了
②给一个任意的日期,查询这个日期对应的月份有多少天
day(last_day(submit_time))
SQL19 group_concat函数
select uid,count(*)-count(submit_time) as incomplete_cnt,
count(submit_time) as complete_cnt,
group_concat(distinct concat(date_format(start_time,'%Y-%m-%d'),':',ei.tag)
order by start_time separator ';') as detail
from exam_record er left join examination_info ei
on er.exam_id=ei.exam_id
where year(start_time)=2021
group by uid
having complete_cnt>=1 and incomplete_cnt<5
and incomplete_cnt>1
order by incomplete_cnt desc;
SQL23 union排序问题
首先明确,union可以使用任何selcet语句,但order by子句只能在最后一次使用
所以,如果想要对未union前两个sql语句的查询结果进行排序,分别单独排序需要的数据,查出以后再使用union连接
select * from (select exam_id as tid,count(distinct ex.uid) as uv,count(*) as pv from exam_record ex
group by exam_id order by uv desc,pv desc) t1
union
select * from (select question_id as tid,count(distinct pr.uid) as uv,count(*) as pv from practice_record pr
group by question_id order by uv desc,pv desc) t2
题目来源:牛客网