05-数据库_数据库高级_SQL进阶面试题

目录

六,SQL进阶面试题

1,一条SQL语句查询出所有成绩大于80的学生姓名

建表语句

解题思路

2,查询后一天 temperature 比前一天高的date

建表语句

解题思路

3,查询每个主播的最大level以及对应的最小gap(注意:不是每个主播的最大level和最小gap)

建表语句

解题思路

4,课程数据行转列

建表语句

解题思路

5,有两个表A和B,均有key和value两个字段,如果B的key在A中也有,就把B的value换为A中对应的value

建表语句

解题思路

6,设计表,关系如下:教师、班级、学⽣、科室、科室与教师为⼀对多关系,教师与班级为多对多关系,班级与学⽣为⼀对多关系,科室中需体现层级关系

写出各张表的逻辑字段

问题

7,说一下你熟悉的数据库,这个数据库有什么特点?

8,你常用的mysql引擎有哪些?各引擎间有什么区别? 

9,请描述MySQL中left join和inner join的区别。 

10,请列出你最常使⽤的mysql版本,mysql默认端⼝号是多少?请写出你最常⽤的mysql数据库备份和恢复命令。 

11,数据库A:datahn,其中具有表c、表d。 数据库B:datapubhn,现想要在数据库B中对数据库A中表c与表d中的字段进⾏增删改查。如何授权?

12,对于处理⾼复杂sql,数据库查询特别慢,你有什么高招? 

13,选择填空题

14,Mysql数据库GD2312、utf8\utf8mb4字符集的区别___。 


六,SQL进阶面试题

1,一条SQL语句查询出所有成绩大于80的学生姓名

建表语句

-- 建表语句
CREATE TABLE `mst_stu` (
 `name` varchar(255) DEFAULT NULL,
 `course` varchar(255) DEFAULT NULL,
 `score` int(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 数据
INSERT INTO `mst_stu` VALUES ('张三', '语⽂', 81);
INSERT INTO `mst_stu` VALUES ('张三', '数学', 75);
INSERT INTO `mst_stu` VALUES ('李四', '语⽂', 76);
INSERT INTO `mst_stu` VALUES ('李四', '数学', 90);
INSERT INTO `mst_stu` VALUES ('王五', '语⽂', 81);
INSERT INTO `mst_stu` VALUES ('王五', '数学', 100);
INSERT INTO `mst_stu` VALUES ('王五', '英语', 90);

解题思路

根据学员进行分组,最低分高于80即符合要求

-- 先根据学员进行分组,看每个人的最低分
select name,min(score) from mst_stu group by name;

-- 在使用分组过滤 having 筛选出最低分大于80
select name,min(score) as min_sc from mst_stu group by name having min_sc > 80;

-- 最终只需要符合要求的学员姓名
select name from mst_stu group by name having min(score) > 80;


2,查询后一天 temperature 比前一天高的date

查找与之前(昨天的)⽇期相⽐温度更⾼的所有⽇期的 Id。

建表语句

-- mst_Weather
CREATE TABLE `mst_weather` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `date` date DEFAULT NULL,
 `temperature` int(255) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
INSERT INTO `mst_weather` VALUES (1, '2022-04-01', 20);
INSERT INTO `mst_weather` VALUES (2, '2022-04-02', 25);
INSERT INTO `mst_weather` VALUES (3, '2022-04-03', 21);
INSERT INTO `mst_weather` VALUES (4, '2022-04-04', 24);

解题思路

两个相同的表做自联结,联结条件是s1表的日期与s2表日期之差为1,且s1表的温度高于s2表的温度

datediff用于计算两个日期之差

select s1.id
from mst_weather as s1
join mst_weather as s2
on datediff(s1.date,s2.date) = 1
and s1.temperature > s2.temperature;


3,查询每个主播的最大level以及对应的最小gap(注意:不是每个主播的最大level和最小gap)

首先锁定最大的level,其次挑选最小的gap

建表语句

CREATE TABLE `mst_zhubo` (
 `zhubo_id` int(11) NOT NULL,
 `level` int(255) DEFAULT NULL,
 `gap` int(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `mst_zhubo` VALUES (123, 8, 20);
INSERT INTO `mst_zhubo` VALUES (123, 9, 40);
INSERT INTO `mst_zhubo` VALUES (123, 9, 30);
INSERT INTO `mst_zhubo` VALUES (246, 6, 30);
INSERT INTO `mst_zhubo` VALUES (246, 6, 20);

解题思路

-- 先查询每个主播的最大 level
select zhubo_id,max(level) from mst_zhubo group by zhubo_id;
+----------+------------+
| zhubo_id | max(level) |
+----------+------------+
|      123 |          9 |
|      246 |          6 |
+----------+------------+
2 rows in set (0.00 sec)

--在这个基础上,查询出每个主播所有符合最大level的数据
select * from mst_zhubo where (zhubo_id,level) in (select zhubo_id,max(level) from mst_zhubo group by zhubo_id)

+----------+-------+------+
| zhubo_id | level | gap  |
+----------+-------+------+
|      123 |     9 |   40 |
|      123 |     9 |   30 |
|      246 |     6 |   30 |
|      246 |     6 |   20 |
+----------+-------+------+
4 rows in set (0.01 sec)

-- 在这个基础上,按照主播分组,求最小的gap
select zhubo_id,level,min(gap)
from mst_zhubo where (zhubo_id,level) in (select zhubo_id,max(level) from mst_zhubo group by zhubo_id)
group by zhubo_id,level;

+----------+-------+----------+
| zhubo_id | level | min(gap) |
+----------+-------+----------+
|      123 |     9 |       30 |
|      246 |     6 |       20 |
+----------+-------+----------+
2 rows in set (0.01 sec)


4,课程数据行转列

建表语句

CREATE TABLE `mst_class` (
 `class_id` varchar(255) NOT NULL,
 `grade` varchar(255) DEFAULT NULL,
 `rate` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `mst_class` VALUES ('abc123', 'primary', '70%');
INSERT INTO `mst_class` VALUES ('abc123', 'middle', '65%');
INSERT INTO `mst_class` VALUES ('abc123', 'high', '72%');
INSERT INTO `mst_class` VALUES ('hjkk86', 'primary', '69%');
INSERT INTO `mst_class` VALUES ('hjkk86', 'middle', '63%');
INSERT INTO `mst_class` VALUES ('hjkk86', 'high', '74%');

解题思路

使用case-when / if-else语句选择各列的值,并取最大值进行替换

--CASE WHEN
select class_id,
max(CASE WHEN grade = 'primary' THEN rate ELSE 0 END) as 'primary',
max(CASE WHEN grade = 'middle' THEN rate ELSE 0 END) as 'middle',
max(CASE WHEN grade = 'high' THEN rate ELSE 0 END) as 'high'
from mst_class
group by class_id;

--IF
select class_id,
max(IF(grade = 'primary',rate,0)) as 'primary',
max(IF(grade = 'middle',rate,0)) as 'middle',
max(IF(grade = 'high',rate,0)) as 'high'
from mst_class
group by class_id;


5,有两个表A和B,均有key和value两个字段,如果B的key在A中也有,就把B的value换为A中对应的value

建表语句

create table `mst_a`(`key` varchar(10),`value` varchar(10));
create table `mst_b`(`key` varchar(10),`value` varchar(10));
insert into mst_a values('A','aaa'),('B','bbb'),('C','ccc');
insert into mst_b values('D','ddd'),('E','eee'),('A','abc');

解题思路

-- 先查询出哪个key符合要求?
select mst_a.key,mst_a.value from mst_a join mst_b on mst_a.key = mst_b.key;

-- update mst_b as up ,(?) as b set up.value = ? where up.key = ?

update mst_b as up,(
    select mst_a.key,mst_a.value from mst_a join mst_b on mst_a.key = mst_b.key
    ) as b
set up.value = b.value where up.key = b.key

注意事项

  • update 后面是可以进行任何查询语句,这个作用等同于 from
  • update 更新的表,不能在set和where中用于子查询
  • update 也可以对多个表进行更新 (sqlserver不行)

6,设计表,关系如下:教师、班级、学⽣、科室、科室与教师为⼀对多关系,教师与班级为多对多关系,
班级与学⽣为⼀对多关系,科室中需体现层级关系

写出各张表的逻辑字段

教师 mst_Teacher

+-----+-----------+------+
| Tid | Tname | Kid |
+-----+-----------+------+
| 1 | 王⽼师 | 1 |
| 2 | 张⽼师 | 2 |
| 3 | 孙⽼师 | 3 |
| 4 | 李⽼师 | 3 |
| 5 | 伊⽼师 | 4 |
+-----+-----------+------+
CREATE TABLE `mst_teacher` (
 `Tid` int PRIMARY KEY AUTO_INCREMENT,
 `Tname` varchar(10),
 `Kid` int
 );
insert into mst_teacher VALUES(1,'王⽼师',1),(2,'张⽼师',2),(3,'孙⽼师',3),
 (4,'李⽼师',3),(5,'伊⽼师',4);

班级 mst_cla

+-----+-------+
| Cid | Cname |
+-----+-------+
| 1 | 1班 |
| 2 | 2班 |
| 3 | 3班 |
+-----+-------+
CREATE TABLE `mst_cla` (
 `Cid` int PRIMARY KEY AUTO_INCREMENT,
 `Cname` varchar(10)
 );
insert into mst_cla VALUES(1,'1班'),(2,'2班'),(3,'3班');

教师&班级 mst_tc

+----+------+------+
| id | Tid | Cid |
+----+------+------+
| 1 | 3 | 1 |
| 2 | 3 | 2 |
| 3 | 3 | 3 |
| 4 | 4 | 1 |
| 5 | 4 | 2 |
| 6 | 4 | 3 |
+----+------+------+
CREATE TABLE `mst_tc` (
 `id` int PRIMARY KEY AUTO_INCREMENT,
 `Tid` int,`Cid` int
 );
insert into mst_tc VALUES(1,3,1),(2,3,2),(3,3,3),(4,4,1),(5,4,2),(6,4,3);

学⽣ mst_St

+-----+--------+------+
| SId | Sname | Cid |
+-----+--------+------+
| 1 | 赵雷 | 1 |
| 2 | 钱电 | 1 |
| 3 | 孙⻛ | 1 |
| 4 | 李云 | 2 |
| 5 | 周梅 | 2 |
| 6 | 吴兰 | 3 |
| 7 | 郑⽵ | 3 |
+-----+--------+------+
CREATE TABLE `mst_St` (
 `SId` int PRIMARY KEY AUTO_INCREMENT,
 `Sname` varchar(20),`Cid` int
 );
insert into mst_St VALUES(1,'赵雷',1),(2,'钱电',1),(3,'孙⻛',1),(4,'李云',2),
(5,'周梅',2),(6,'吴兰',3),(7,'郑⽵',3);

科室 mst_ks

+-----+-------------+------+
| Kid | Kname | Pid |
+-----+-------------+------+
| 1 | 校⻓室 | 0 |
| 2 | 教学处 | 1 |
| 3 | ui办公室 | 2 |
| 4 | h5办公室 | 2 |
+-----+-------------+------+
CREATE TABLE `mst_ks` (
 `Kid` int PRIMARY KEY AUTO_INCREMENT,
 `Kname` varchar(20),`Pid` int
 );
insert into mst_ks VALUES(1,'校⻓室',0),(2,'教学处',1),(3,'ui办公室',2),(4,'h5办公
室',2);

问题

查询教师id=4的学⽣数

-- 已知教师Id就可以先到教师与班级的关系表中获取当前⽼师所带的班级
select cid from mst_tc where Tid = 4;
-- 获取所带班级后,到学⽣表中获取所带班级中的学员数即可
select count(*) from mst_St where Cid in (select cid from mst_tc where Tid =
4);

查询科室id=2的下级部⻔数

-- 科室id=3的下级部⻔的pid也就等于科室id,因此查询当前科室的⽗级id = 2的即可
select count(*) from mst_ks where pid = 2;

查询所带学⽣最多的教师id

-- 先查询出每个⽼师带的学⽣数
select t.tid,t.tname,count(stu.sid)
from mst_teacher as t join mst_tc on t.tid = mst_tc.tid
join mst_st as stu on stu.cid = mst_tc.cid
group by t.tid,t.tname;
+-----+-----------+----------------+
| tid | tname | count(stu.sid) |
+-----+-----------+----------------+
| 3 | 孙⽼师 | 7 |
| 4 | 李⽼师 | 5 |
+-----+-----------+----------------+
-- 在以上结果的基础上,按照学⽣数排序,取⼀个
select t.tid,t.tname,count(stu.sid) as num
from mst_teacher as t join mst_tc on t.tid = mst_tc.tid
join mst_st as stu on stu.cid = mst_tc.cid
group by t.tid,t.tname order by num desc limit 1;

7,说一下你熟悉的数据库,这个数据库有什么特点?

mysql 关系型数据库 开源中最常⽤的数据库,有多种表引擎,⽀持事务,⽀持表关系 

redis 非关系型数据库,键值对的存储⽅式,并且数据存储在内存中,有多种不同的数据类型 

mongodb 非关系型数据库,基于分布式⽂件存储的数据库,是nosql中最像关系型数据库的


8,你常用的mysql引擎有哪些?各引擎间有什么区别? 

myisam 存储由三个⽂件组成,⼀个存储表结构,⼀个存储数据,⼀个存储索引。不⽀持事务,⾮聚簇索引 

innodb 存储由两个⽂件组成,⼀个存储表结构,⼀个存储数据和索引。⽀持事务,主索引是聚簇索引,并且表中始终存在主键(即便在建表是没有创建主键)


9,请描述MySQL中left join和inner join的区别。 

join 和 inner join 都是⼀样的,会连接两个表中存在关系字段的数据 和 where的关联查询⼀样

left join 和 right join⼀样 都是以左表(或右表)数据为基准,去查询另外⼀个表的数据, 如果没有对应字段的数据,则补充为null


10,请列出你最常使⽤的mysql版本,mysql默认端⼝号是多少?请写出你最常⽤的mysql数据库备份和恢复命令。 

5.7, 端⼝ 3306 127.0.0.1 localhost 本机的IP

-- 数据导⼊ mysql -uroot -p < F:\mysql-5.7.27-winx64\bf\ops.sql
-- 数据备份 导出 mysqldump -uroot -p -B -F -R -x --master-data=2 ops >F:\mysql-5.7.27-winx64\bf\ops.sql

参数说明:
-B:指定数据库 -F:刷新⽇志 -R:备份存储过程等 -x:锁表 --master-data:在备份语句⾥添加CHANGE MASTER语句以及binlog⽂件及位置点信息


11,数据库A:datahn,其中具有表c、表d。 数据库B:datapubhn,现想要在数据库B中对数据库A中表c与表d中的字段进⾏增删改查。如何授权?

grant select,insert,update,delete on B.*,A.c,A.d to'zhansgan'@'%' identified by '123456


12,对于处理⾼复杂sql,数据库查询特别慢,你有什么高招? 

  • 复杂查询简单化 
  • 不⽤嵌套
  • 不⽤join
  • 多表查询
  • 拆分 
  • 针对语句的查询字段设计索引,给经常作为where条件的字段添加索引,必要时添加联合索引

13,选择填空题

以下哪条语句在数据库sql书写时最为⾼效(B)

  • A.select * from emp where dep>3
  • B.select * from emp where dep>=4
  • C.select * from emp where dep≥4
  • D.select * from emp where dep>=3 and dep≠4

数据库中执⾏删除操作,若要删除表中的所有⾏,建议使⽤(B)

  • A.delete 语句
  • B.turncate 语句
  • C.drop 语句
  • D.commit 语句

在查询语句的select⼦句中尽量避免使⽤ * 来表示全部列名

查找条件为:姓名不是NULL的纪录(C)

  • A.WHERE NAME ! NULL
  • B.WHERE NAME NOT NULL
  • C.WHERE NAME IS NOT NULL
  • D.WHERE NAME!=NULL

在SQL语⾔中,⼦查询是(D)

  • A.选取单表中字段⼦集的查询语句
  • B.选取多表中字段⼦集的查询语句
  • C.返回单表中数据⼦集的查询语⾔
  • D.嵌⼊到另⼀个查询语句之中的查询语句

以下能够删除⼀列的是(B)

  • A.alter table emp remove addcolumn
  • B.alter table emp drop column addcolumn
  • C.alter table emp delete column addcolumn
  • D.alter table emp delete addcolumn

学⽣关系模型S(S#,Sname,Sex,Age),S的属性分别表示学⽣的学号、姓名、性别、年龄。要在表S中删除⼀个属性”年龄”,可选⽤的SQL语句是(D)

  • A.UPDATE S Age
  • B.DELETE Age from S
  • C.ALTER TABLE S ‘Age’
  • D.ALTER TABLE S DROP Age

14,Mysql数据库GD2312、utf8\utf8mb4字符集的区别___。 

GD2312 收录了6763个汉字,其它⽂字符号682个,兼容ASCII字符 占⽤空间: 如果是ASCII字符,则占⼀个字节编码 如果是否其它则采⽤2个字节编码

UTF8 收录地球上能想到的所有字符,⽽且还在不断扩充,同时兼容ASCII字符 存储空间为 1-4个字节

  • utf8mb3 :阉割过的 utf8`字符集,只使⽤1~3个字节表示字符。
  • utf8mb4 :正宗的 utf8 字符集,使⽤1~4个字节表示字符。

猜你喜欢

转载自blog.csdn.net/qq_41528502/article/details/113919787