INSERT INTO exam_record (uid, exam_id, start_time, submit_time, score) VALUES
(1001, 9001, '2021-09-01 22:11:12', '2021-09-01 23:01:12', 90),
(1002, 9002, '2021-09-04 07:01:02', NULL, NULL);
明确考点:
插入记录的方式汇总:
思路实现:
本题可采用第四种插入方式,需根据细节剖析的点做稍微改动,改为限定字段插入,即只插入除自增id列以外的列:
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(submit_time) < '2021';
当然上面的WHERE里简化了细节剖析里的后两个条件,也可以分开来筛选,写作:
WHERE YEAR(start_time) < '2021' and submit_time IS NOT NULL;
注意:该数据可能存在
思路实现:
解法一:
REPLACE INTO examination_info
VALUES(NULL,9003,'SQL','hard',90,'2021-01-01 00:00:00');
replace into 跟 insert into功能类似,不同点在于:replace into 首先尝试插入数据到表中,
如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据;
否则,直接插入新数据。
要注意的是:插入数据的表必须有主键或者是唯一索引!否则的话,replace into 会直接插入数据,这将导致表中出现重复的数据。
解法二:
DELETE FROM examination_info
WHERE exam_id=9003;
INSERT INTO examination_info
VALUES(NULL,9003, 'SQL','hard', 90, '2021-01-01 00:00:00')
题目: 请把examination_info表中tag为PYTHON的tag字段全部修改为Python。
明确考点:
修改记录的方式汇总:
思路实现:
本题采用两种修改方式均可,语义为『当tag为PYTHON时,修改tag为Python』,先用第一种:
UPDATE examination_info
SET tag = "Python"
WHERE tag = "PYTHON";
如果采用第二种,写作:(推荐)
推荐使用:查询时间更短,占用内存更少,与第一种相比
UPDATE examination_info
SET tag = REPLACE(tag, "PYTHON", "Python")
WHERE tag = "PYTHON";
思维扩展:第二种方式不仅可用于整体替换,还能做子串替换,例如要实现将tag中所有的PYTHON替换为Python(如CPYTHON=>CPython),可写作:
UPDATE examination_info
SET tag = REPLACE(tag, "PYTHON", "Python")
WHERE tag LIKE "%PYTHON%";
明确考点:
修改记录的方式汇总:
细节剖析:
思路实现:
本题宜采用第一种修改方式,满足条件1和条件2就修改:
UPDATE exam_record
SET submit_time='2099-01-01 00:00:00', score=0
WHERE start_time < '2021-09-01 00:00:00' AND score IS NULL;
明确考点:
删除记录的方式汇总:
时间差:
TIMESTAMPDIFF(interval, time_start, time_end)可计算time_start-time_end的时间差,单位以指定的interval为准,常用可选:
细节剖析:
思路实现:
本题采用第一种删除方式,满足条件1和条件2就删除:
DELETE FROM exam_record
WHERE TIMESTAMPDIFF(MINUTE, start_time, submit_time) < 5
AND score < 60;
细节剖析:
思路实现:
本题采用第一种删除方式,满足条件1或条件2就删除,但只删除3条记录:
DELETE FROM exam_record
OR TIMESTAMPDIFF(MINUTE, start_time, submit_time) < 5
ORDER BY start_time
LIMIT 3;
题目: 请删除exam_record表中所有记录,并重置自增主键。
明确考点:
删除记录的方式汇总:
详解:truncate table 和 delete
truncate table 在功能上,与不带where字句的delete语句相同;二者均删除表中的全部行,但truncate table 比delete速度更快,且使用的系统和事务日志资源少。 truncate 删除表中的所有行,但表的结构及其列,约束,索引等保持不变。新行标识所用的技术值重置为该列的种子。如果想保留标识计数值,轻盖拥delete 。如果要删除表定义及其数据,请使用drop table 语句。
细节剖析:
思路实现:
方式一:(推荐使用)
TRUNCATE exam_record;
方式二:
DELETE FROM exam_record;
ALTER TABLE exam_record auto_increment=1;
明确考点:
表的创建、修改与删除:
CREATE TABLE
[IF NOT EXISTS] tb_name -- 不存在才创建,存在就跳过
(column_name1 data_type1 -- 列名和类型必选
[ PRIMARY KEY -- 可选的约束,主键
| FOREIGN KEY -- 外键,引用其他表的键值
| AUTO_INCREMENT -- 自增ID
| COMMENT comment -- 列注释(评论)
| DEFAULT default_value -- 默认值
| UNIQUE -- 唯一性约束,不允许两条记录该列值相同
| NOT NULL -- 该列非空
], ...
) [CHARACTER SET charset] -- 字符集编码
[COLLATE collate_value] -- 列排序和比较时的规则(是否区分大小写等)
1.2 从另一张表复制表结构创建表: CREATE TABLE tb_name LIKE tb_name_old
1.3 从另一张表的查询结果创建表: CREATE TABLE tb_name AS SELECT * FROM tb_name_old WHERE options
2.1 修改表:ALTER TABLE 表名 修改选项
。选项集合:
{ ADD COLUMN <列名> <类型> -- 增加列
| CHANGE COLUMN <旧列名> <新列名> <新列类型> -- 修改列名或类型
| ALTER COLUMN <列名> { SET DEFAULT <默认值> | DROP DEFAULT } -- 修改/删除 列的默认值
| MODIFY COLUMN <列名> <类型> -- 修改列类型
| DROP COLUMN <列名> -- 删除列
| RENAME TO <新表名> -- 修改表名
| CHARACTER SET <字符集名> -- 修改字符集
| COLLATE <校对规则名> } -- 修改校对规则(比较和排序时用到)
3.1 删除表:DROP TABLE [IF EXISTS] 表名1 [ ,表名2]
细节剖析:
思路实现:
本题采用第1种创建方式,根据细节剖析中的点组织完整创建语句:
CREATE TABLE IF NOT EXISTS 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 '注册时间'
) CHARACTER SET utf8 COLLATE utf8_general_ci;
题目:
请在用户信息表,字段level的后面增加一列最多可保存15个汉字的字段school;并将表中job列名改为profession,同时varchar字段长度变为10;achievement的默认值设置为0。
思路实现:
alter table user_info add school varchar(15) after level;
# 增加列在某列之后
alter table 增加的表格 add 增加列的名称 数据类型 位置(after level 在level 之后)
alter table user_info change job profession varchar(10);
# 更换列的名称及数据类型
alter table user_info change 原列名 修改列名 修改数据类型
alter table user_info modify achievement int(11) default 0;
#更改数据类型
alter table 表名 modify 修改列名称 数据类型 默认值等
细节剖析:
思路实现:
本题采用第1种删除方式,根据细节剖析中的点组织完整语句:
DROP TABLE IF EXISTS exam_record_2011, exam_record_2012, exam_record_2013, exam_record_2014;
题目:
现有一张试卷信息表examination_info,其中包含各种类型试卷的信息。为了对表更方便快捷地查询,需要在examination_info表创建以下索引,规则如下:
在duration列创建普通索引idx_duration、在exam_id列创建唯一性索引uniq_idx_exam_id、在tag列创建全文索引full_idx_tag。
思路实现:
# 方法一:
# 普通索引
CREATE INDEX idx_duration ON examination_info(duration);
# 唯一索引
CREATE UNIQUE INDEX uniq_idx_exam_id ON examination_info(exam_id);
# 全文索引
CREATE FULLTEXT INDEX full_idx_tag ON examination_info(tag);
# 方法二:(效率更高)
alter table examination_info add index idx_duration(duration);
alter table examination_info add unique uniq_idx_exam_id(exam_id);
alter table examination_info add Fulltext full_idx_tag(tag);
题目:
请删除examination_info表上的唯一索引uniq_idx_exam_id和全文索引full_idx_tag。
思路实现:
# 方法一:(效率更高)
alter table examination_info drop index uniq_idx_exam_id;
alter table examination_info drop index full_idx_tag;
# 方法二:
drop index uniq_idx_exam_id on examination_info;
drop index full_idx_tag on examination_info;
明确题意:
计算所有用户完成SQL类别高难度试卷得分的截断平均值(去掉一个最大值和一个最小值后的平均值)
问题分解:
细节问题:
思路实现:
select tag, difficulty,
round((sum(score) - max(score) - min(score)) / (count(score) - 2), 1) as clip_avg_score
from exam_record
join examination_info using(exam_id)
where tag="SQL" and difficulty="hard"
明确题意:
统计出总作答次数total_pv、试卷已完成作答数complete_pv、已完成的试卷数complete_exam_cnt
问题分解:
count(distinct if(submit_time is not null, exam_id, null)) as complete_exam_cnt
细节问题:
思路实现:
select
count(exam_id) as total_pv,
count(submit_time) as complete_pv,
count(distinct if(submit_time is not null, exam_id, null)) as complete_exam_cnt
from exam_record
明确题意:
问题分解:
1.要找类别为SQL的试卷平均得分:
1、得分信息在exam_record,试卷类别在表examination_info中,因此要将两个表以exam_id连接。知识点:join…on…
2、 从连接后的表中找到类别为SQL的试卷的分数。知识点:select…from…where… 3、
3、 计算得分的平均值。知识点:avg()
2.找到类别SQL的试卷得分大于平均得分的最小值:
1、得分信息在exam_record,试卷类别在表examination_info中,因此要将两个表以exam_id连接。知识点:join…on…
2、从连接后的表中找到类别为SQL的试卷且分数大于刚刚找到的平均分的分数。知识点:select…from…where…and…
3、从中选出最小值。知识点:min()
思路实现:
select min(e_r.score) as min_score_over_avg
from exam_record e_r join examination_info e_i
on e_r.exam_id = e_i.exam_id
where e_i.tag = 'SQL'
and score >= (select avg(e1.score)
from exam_record e1 join examination_info e2
on e1.exam_id = e2.exam_id
where tag = 'SQL'
)
关注林哥,持续更新哦!!!★,°:.☆( ̄▽ ̄)/$:.°★ 。