文章目录
MySQL面试题
有如下一张表,按结果要求的格式写出SQL语句
match_record
表:
match_date | result |
---|---|
2023-2-10 | 胜 |
2023-2-10 | 胜 |
2023-2-10 | 负 |
2023-2-10 | 负 |
2023-2-10 | 负 |
2023-2-11 | 胜 |
2023-2-11 | 负 |
2023-2-11 | 负 |
结果:
比赛日期 | 胜 | 负 |
---|---|---|
2023-2-10 | 2 | 3 |
2023-2-11 | 1 | 2 |
导入数据:
drop table if exists match_record;
create table match_record(
match_date date,
result char(1)
);
insert into match_record values
('2023-2-10', '胜'),
('2023-2-10', '胜'),
('2023-2-10', '负'),
('2023-2-10', '负'),
('2023-2-10', '负'),
('2023-2-11', '胜'),
('2023-2-11', '负'),
('2023-2-11', '负');
答案:
# result字段数据,处理成两列
select match_date,
result,
case result
when '胜' then 1
end 胜,
case result
when '负' then 1
end 负
from match_record;
# 对胜负两列计数
select match_date,
count(case result
when '胜' then 1
end) 胜,
count(case result
when '负' then 1
end) 负
from match_record
group by match_date;
# 也可以用行内视图的方式查询
select match_date, count(胜) 胜, count(负) 负
from (
select match_date,
case result
when '胜' then 1
end 胜,
case result
when '负' then 1
end 负
from match_record
) t
group by match_date;
有一张表student,包括字段id和name,请写一条sql语句,将表中name字段中重复的记录删除,只保留重复数据中的id最大的那一条数据。
id | name |
---|---|
1 | 张三 |
2 | 张三 |
3 | 李四 |
4 | 王五 |
5 | 王五 |
6 | 王五 |
导入数据:
drop table if exists student;
create table student(
id int,
name varchar(50)
);
insert into student values
(1,'张三'),
(2,'张三'),
(3,'李四'),
(4,'王五'),
(5,'王五'),
(6,'王五');
答案:
select max(id) from student
group by name;
delete from student where id not in(
select max(id) from student
group by name
);
# mysql 8, 不能从同一张表查询再删除
# 可以再嵌套一层行内视图,命名为t,外面删除用student表,里面查询用t表
delete from student where id not in(
select id from (
select max(id) id from student
group by name
) t
);
SQL数据库表名为guest,请简答
account | details | date | money | class |
---|---|---|---|---|
s0001 | 房费 | 2020-01-01 | 280 | 001 |
s0001 | 酒水 | 2020-01-02 | 120 | 001 |
s0001 | 房费 | 2020-01-08 | 300 | 003 |
s0002 | 酒水 | 2020-01-29 | 50 | |
s0003 | 房费 | 2020-01-31 | 180 | 002 |
s0004 | 房费 | 2020-02-01 | 230 | 001 |
s0005 | 酒水 | 2020-02-01 | 100 | |
s0005 | 房费 | 2020-02-02 | 128 | 001 |
导入数据:
drop table if exists guest;
create table guest(
account varchar(20),
details varchar(20),
date date,
money int,
class varchar(10)
);
insert into guest values
('s0001','房费','2020-01-01',280,'001'),
('s0001','酒水','2020-01-02',120,'001'),
('s0001','房费','2020-01-08',300,'003'),
('s0002','酒水','2020-01-29',50,null),
('s0003','房费','2020-01-31',180,'002'),
('s0004','房费','2020-02-01',230,'001'),
('s0005','酒水','2020-02-01',100,null),
('s0005','房费','2020-02-02',128,'001');
查询出1月份每个账号酒水和房费的总金额
account | sum(money) |
---|---|
s0001 | 700 |
s0002 | 50 |
s0003 | 180 |
答案:
select account,sum(money)
from guest
where date>='2020-01-01' and date<'2020-02-01'
group by account;
查询出全部房费都大于200的账号
account |
---|
s0001 |
s0004 |
答案:
select account
from guest
where details='房费'
group by account
having min(money)>200;
看下面的数据表,按要求写SQL
a表:
保存客户的基本信息
NO(客户号) | NAME(姓名) | ID(身份证) | BIRTH(出生日期) | COUNTRY(国籍) |
---|---|---|---|---|
001 | 张三 | 310111XXXXX1 | 19900101 | 中国 |
002 | 李四 | 310111XXXXX2 | 19800201 | 中国 |
003 | 王五 | 310111XXXXX3 | 19850301 | 中国 |
004 | 赵六 | 310111XXXXX4 | 19930401 | 美国 |
b表:
保存客户的资产和负债信息
NO(客户号) | DEPOSIT(存款金额) | CREDIT(信用卡余额) |
---|---|---|
001 | 10001.00 | -100.00 |
002 | 1000.00 | -2000.00 |
003 | 0.00 | -5000.00 |
004 | 100.01 | 0.00 |
导入数据:
drop table if exists a;
create table a(
no varchar(10),
name varchar(20),
id varchar(18),
birth char(8),
country varchar(20)
);
insert into a values
('001', '张三', '310111xxx1', 19900101, '中国'),
('002', '李四', '310111xxx2', 19800201, '中国'),
('003', '王五', '310111xxx3', 19850301, '中国'),
('004', '赵六', '310111xxx4', 19930401, '美国');
drop table if exists b;
create table b(
no varchar(10),
deposit decimal(15,2),
credit decimal(15,2)
);
insert into b values
('001', 10001.00, -100.00),
('002', 1000.00, -2000.00),
('003', 0.00, -5000.00),
('004', 100.01, 0.00);
写SQL查询:按国籍统计客户号的数量,统计结果要求格式如下:
国籍 | 数量 |
---|---|
中国 | XXX |
美国 | XXX |
答案:
select country, count(*)
from a
group by country;
统计80后、90后的信用卡余额总额,统计结果要求格式如下:
年龄段 | 信用卡余额 |
---|---|
80后 | XXX |
90后 | XXX |
答案:
(select '80后' 年龄段, sum(credit)
from a
join b on a.no=b.no
where birth between '19800101' and '19891231')
union
(select '90后' 年龄段, sum(credit)
from a
join b on a.no=b.no
where birth between '19900101' and '19991231')
看下面的数据表,写出SQL语句
student表:
id | name |
---|---|
1 | Tom |
2 | Jerry |
3 | Henson |
class表:
id | name |
---|---|
1 | Math |
2 | English |
3 | Computer |
resultsheet表:
id | sid | cid | result |
---|---|---|---|
1 | 1 | 1 | 70 |
2 | 2 | 1 | 80 |
3 | 3 | 1 | 90 |
4 | 2 | 2 | 75 |
5 | 3 | 2 | 85 |
6 | 1 | 3 | 95 |
注:sid是外键,引用student(id);cid是外键,引用class(id)
导入数据:
create table student(
id int,
name varchar(20)
);
drop table if exists class;
create table class(
id int,
name varchar(20)
);
drop table if exists resultsheet;
create table resultsheet(
id int,
sid int,
cid int,
result int
);
insert into student values
(1, 'Tom'),
(2, 'Jerry'),
(3, 'Henson');
insert into class values
(1, 'Math'),
(2, 'English'),
(3, 'Computer');
insert into resultsheet values
(1, 1, 1, 70),
(2, 2, 1, 80),
(3, 3, 1, 90),
(4, 2, 2, 75),
(5, 3, 2, 85),
(6, 1, 3, 95);
select * from student;
select * from class;
select * from resultsheet;
写出每门课程平均分数的SQL语句,要求输出结果如下:
课程 | 平均分数 |
---|---|
Computer | 95 |
English | 80 |
Math | 80 |
写出能得到下面结果的SQL语句:
姓名 \ 科目 | Computer | English | Math |
---|---|---|---|
Henson | - | 85 | 90 |
Jerry | - | 75 | 80 |
Tom | 95 | - | 70 |
写sql语句,查询科目“English”没有成绩的同学的学号和姓名,要求得到下面的结果:
id | name |
---|---|
1 | Tom |
答案:
select c.name '课程', round(avg(r.result), 1) '平均成绩'
from resultsheet r
join class c on r.cid=c.id
group by c.name;
# 第一步:连接三张表,查询学生,课程,成绩
select s.name, c.name, r.result
from resultsheet r
join student s on r.sid=s.id
join class c on r.cid=c.id;
# 第二步:后面添加三列,分别放三门课程的成绩
select s.name, c.name, r.result,
case c.name
when 'Math' then r.result
end 'Math',
case c.name
when 'English' then r.result
end 'English',
case c.name
when 'Computer' then r.result
end 'Computer'
from resultsheet r
join student s on r.sid=s.id
join class c on r.cid=c.id;
# 第三步:按学生名分组,分别对三列课程成绩求最大值,也是这一列中的唯一的一个值
select s.name,
max(case c.name
when 'Math' then r.result
end) 'Math',
max(case c.name
when 'English' then r.result
end) 'English',
max(case c.name
when 'Computer' then r.result
end) 'Computer'
from resultsheet r
join student s on r.sid=s.id
join class c on r.cid=c.id
group by s.name;
# 查询有英语成绩的
select r.sid
from resultsheet r
join class c on r.cid=c.id
where c.name='English';
# 把有英语成绩的学生排除,就是查询没有英语成绩的
select id, name
from student
where id not in(
select r.sid
from resultsheet r
join class c on r.cid=c.id
where c.name='English'
);
在以下两张表中按要求查询数据:
导入数据:
# 学生的成绩表
drop table if exists student_score;
create table student_score(
id varchar(8),
name varchar(50),
gender varchar(4),
course_id varchar(5) comment '课程ID',
score int comment '成绩',
ismakeup tinyint comment '是否是补考,0不是补考,1是补考'
);
# 课程表
drop table if exists course;
create table course(
id varchar(5),
name varchar(30) comment '课程名',
`desc` varchar(60) comment '描述'
);
insert into course values
('A01', '数学', '数学课'),
('A02', '语文', '语文课'),
('A03', '英语', '英语课'),
('A04', '物理', '物理课'),
('A05', '化学', '化学课');
insert into student_score values
('T0001', '张三', '男', 'A01', 74, 0),
('T0001', '张三', '男', 'A02', 51, 0),
('T0001', '张三', '男', 'A03', 67, 0),
('T0001', '张三', '男', 'A04', 91, 0),
('T0001', '张三', '男', 'A05', 49, 0),
('T0001', '张三', '男', 'A02', 68, 1),
('T0001', '张三', '男', 'A05', 70, 1),
('T0002', '李四', '女', 'A01', 55, 0),
('T0002', '李四', '女', 'A02', 68, 0),
('T0002', '李四', '女', 'A03', 82, 0),
('T0002', '李四', '女', 'A04', 90, 0),
('T0002', '李四', '女', 'A05', 77, 0),
('T0002', '李四', '女', 'A01', 62, 1),
('T0003', '王五', '女', 'A01', 81, 0),
('T0003', '王五', '女', 'A02', 63, 0),
('T0003', '王五', '女', 'A03', 57, 0),
('T0003', '王五', '女', 'A04', 81, 0),
('T0003', '王五', '女', 'A05', 85, 0),
('T0003', '王五', '女', 'A03', 71, 1),
('T0004', '赵六', '男', 'A01', 73, 0),
('T0004', '赵六', '男', 'A02', 88, 0),
('T0004', '赵六', '男', 'A03', 62, 0),
('T0004', '赵六', '男', 'A04', 91, 0),
('T0004', '赵六', '男', 'A05', 83, 0),
('T0005', '孙七', '女', 'A01', 44, 0),
('T0005', '孙七', '女', 'A02', 51, 0),
('T0005', '孙七', '女', 'A03', 49, 0),
('T0005', '孙七', '女', 'A04', 67, 0),
('T0005', '孙七', '女', 'A05', 50, 0),
('T0005', '孙七', '女', 'A03', 62, 1),
('T0005', '孙七', '女', 'A02', 70, 1),
('T0005', '孙七', '女', 'A01', 64, 1),
('T0005', '孙七', '女', 'A05', 62, 1),
('T0006', '周八', '男', 'A01', 80, 0),
('T0006', '周八', '男', 'A02', 75, 0),
('T0006', '周八', '男', 'A03', 79, 0),
('T0006', '周八', '男', 'A04', 55, 0),
('T0006', '周八', '男', 'A05', 70, 0),
('T0006', '周八', '男', 'A04', 74, 1),
('T0007', '吴九', '男', 'A01', 88, 0),
('T0007', '吴九', '男', 'A02', 95, 0),
('T0007', '吴九', '男', 'A03', 68, 0),
('T0007', '吴九', '男', 'A04', 89, 0),
('T0007', '吴九', '男', 'A05', 77, 0);
查找第一次考试后所有需要补考(小于60分)的学生姓名和这门课程的名称和成绩
学生 | 课程 | 成绩 |
---|---|---|
孙七 | 数学 | 44 |
李四 | 数学 | 55 |
孙七 | 语文 | 51 |
张三 | 语文 | 51 |
孙七 | 英语 | 49 |
王五 | 英语 | 57 |
周八 | 物理 | 55 |
孙七 | 化学 | 50 |
张三 | 化学 | 49 |
答案:
select s.name 学生, c.name 课程, s.score 成绩
from student_score s
join course c on s.course_id=c.id
where ismakeup=0 and score<60;
查询每个学生第一次考试后需要补考(小于60分)的课程平均分和科目数
ID | 学生 | 补考科目 | 平均成绩 |
---|---|---|---|
T0005 | 孙七 | 4 | 48.5000 |
T0002 | 李四 | 1 | 55.0000 |
T0001 | 张三 | 2 | 50.0000 |
T0003 | 王五 | 1 | 57.0000 |
T0006 | 周八 | 1 | 55.0000 |
答案:
select s.id, s.name 学生, count(*) 补考科目, avg(s.score) 平均成绩
from student_score s
join course c on s.course_id=c.id
where ismakeup=0 and score<60
group by s.id, s.name;
查询所有参加了补考的学生的学生姓名,课程名称,补考成绩和非补考成绩
学生 | 课程 | 第一次考试 | 补考考试 |
---|---|---|---|
孙七 | 数学 | 44 | 64 |
李四 | 数学 | 55 | 62 |
孙七 | 语文 | 51 | 70 |
张三 | 语文 | 51 | 68 |
孙七 | 英语 | 49 | 62 |
王五 | 英语 | 57 | 71 |
周八 | 物理 | 55 | 74 |
孙七 | 化学 | 50 | 62 |
张三 | 化学 | 49 | 70 |
答案:
select distinct id, course_id from student_score where ismakeup=1;
select s.name 学生, c.name 课程, s.score 成绩
from student_score s
join course c on s.course_id=c.id
where (s.id, s.course_id) in(
select distinct id, course_id from student_score where ismakeup=1
);
select s.name 学生, c.name 课程, s.score 成绩, s.ismakeup,
case ismakeup
when 0 then s.score
end 第一次考试,
case ismakeup
when 1 then s.score
end 补考考试
from student_score s
join course c on s.course_id=c.id
where (s.id, s.course_id) in(
select distinct id, course_id from student_score where ismakeup=1
);
select s.name 学生, c.name 课程,
max(case ismakeup
when 0 then s.score
end) 第一次考试,
max(case ismakeup
when 1 then s.score
end) 补考考试
from student_score s
join course c on s.course_id=c.id
where (s.id, s.course_id) in(
select distinct id, course_id from student_score where ismakeup=1
)
group by s.name,c.name;
在下面的表中按要求查询数据
create database db2;
use db2;
create table student(
s_no varchar(12),
sname varchar(20),
sage int,
sex char(1)
);
create table course(
c_no varchar(12),
cname varchar(20),
t_no varchar(12)
);
create table sc(
s_no varchar(12),
c_no varchar(12),
score int
);
create table teacher(
t_no varchar(12),
tname varchar(20)
);
insert into student values
('001','张三',12,'男'),
('002','李四',11,'女'),
('003','王五',12,'女'),
('004','赵六',11,'女'),
('005','孙七',12,'男');
insert into course values
('001','语文','001'),
('002','数学','002'),
('003','英语','003');
insert into sc values
('001','001',95),('001','002',70),('001','003',74),
('002','001',69),('002','002',78),
('003','001',82),('003','002',58),('003','003',62),
('004','001',55),('004','003',87),
('005','001',77),('005','002',82),('005','003',88);
insert into teacher values
('001','张老师'),
('002','刘老师'),
('003','叶平');
查询001课程比002课程成绩高的全部学生的学号
SELECT DISTINCT s_no
FROM sc s
WHERE c_no = '001' AND score > (SELECT score FROM sc WHERE s_no = s.s_no AND c_no = '002');
查询全部同学的学号、姓名、选课数、总成绩
select s.s_no, s.sname,
count(sc.c_no) c_count, sum(sc.score) sum_score
from student s
join sc on s.s_no=sc.s_no
group by s.s_no, s.sname;
查询没有学全部课程的学生的选号和姓名
SELECT s.s_no, s.sname
FROM student s
WHERE s.s_no IN (
SELECT sc.s_no
FROM sc
GROUP BY sc.s_no
HAVING COUNT(DISTINCT sc.c_no) <> (
SELECT COUNT(*) FROM course
)
);
把sc表中叶平老师教的课的成绩,都改成此课程的平均成绩
update sc set score=(
select avg_score from (
select avg(sc.score) avg_score from sc join course c on sc.c_no=c.c_no join teacher t on c.t_no=t.t_no where t.tname='叶平'
) t
) where c_no=(
select c.c_no from course c join teacher t on c.t_no=t.t_no where t.tname='叶平'
);
删除叶平老师的课程在sc表中的记录
DELETE FROM sc WHERE c_no IN
(SELECT c_no FROM course WHERE t_no IN
(SELECT t_no FROM teacher WHERE tname = '叶平')
);
查询各科成绩最高分和最低分,以以下形式显示:课程ID,最高分,最低分
SELECT c_no, MAX(score) AS highest_score, MIN(score) AS lowest_score
FROM sc
GROUP BY c_no;
查询每门课程的选修人数,按人数降序排列,人数相同按课程号升序排列,要求显示课程号和选修人数
SELECT c_no, COUNT(*) AS student_count
FROM sc
GROUP BY c_no
ORDER BY student_count DESC, c_no ASC;
统计各科不同分数段的人数,要求显示:课程ID,课程名称,100-85,85-70,70-60,<60
SELECT
c.c_no,
c.cname,
COUNT(CASE WHEN s.score BETWEEN 85 AND 100 THEN 1 ELSE NULL END) AS '100-85',
COUNT(CASE WHEN s.score BETWEEN 70 AND 84 THEN 1 ELSE NULL END) AS '85-70',
COUNT(CASE WHEN s.score BETWEEN 60 AND 69 THEN 1 ELSE NULL END) AS '70-60',
COUNT(CASE WHEN s.score < 60 THEN 1 ELSE NULL END) AS '<60'
FROM
sc AS s
JOIN course AS c ON s.c_no = c.c_no
GROUP BY
c.c_no,c.cname
ORDER BY
s.c_no;