SQL语法

在这里插入图片描述

一、DDL:操作数据库/表

(对库database:增 删 查(没有改))
  1. 查库:

    show databases;
    
  2. 创建库:

    create database 库名;   
    
    1. 1 如果不存在则创建:

      create database if not exists 库名;
      
  3. 删除库:

    drop database 库名; 
    
    1. 1 如果存在则删除:

      drop database if exists 库名;
      
  4. 使用数据库(进入数据库)

use 库名;

​ 查看当前使用的数据库:

  select database() ;

–DDL操作表(对表(table):增create 删retrieve 改update 查desc)crud

1. 查表:

show tables;
  1. 1查表结构:

    desc 表名;
    

2. 创建表:

create table 表名(
	字段名1  数据类型1,
	字段名2  数据类型2,
	...    
	字段名n  数据类型n
);

练习:
是

create table tb_user(
	id int,  #属性在前面,类型在后面(和Java语法相反)
	username varchar(20),
	password varchar(30)
);

3. sql数据类型:

数值

tinyint : 小整数型,占一个字节 
int : 大整数类型,占四个字节 
		eg : age int 
double : 浮点类型 
		使用格式: 字段名 double(总长度,小数点后保留的位数) 
		eg : score double(5,2) 意思是总长度为5,少数点后保留2位数

日期:

date : 日期值。只包含年月日 
		eg :birthday date
datetime : 混合日期和时间值。包含年月日时分秒

字符串:

char : 定长字符串。 
	优点: 存储性能高 
	缺点: 浪费空间 
	eg : name char(10) 如果存储的数据字符个数不足10个,也会占10个的空间
    比如存储张三2个字符的,会占到10个空间,因为多余的8个空间会用空格代替,会浪费空间

varchar : 变长字符串。 
	优点: 节约空间 
	缺点: 存储性能底 
	eg : name varchar(10) 如果存储的数据字符个数不足10个,那就数据字符个数是几就占几个的空间

练习:

需求: 设计一张学生表,请注重数据类型、长度的合理性 
	1. 编号 
	2. 姓名,姓名最长不超过10个汉字 
	3. 性别,因为取值只有两种可能,因此最多一个汉字 
	4. 生日,取值为年月日 
	5. 入学成绩,小数点后保留两位 
	6. 邮件地址,最大长度不超过 64 
	7. 家庭联系电话,不一定是手机号码,可能会出现 - 等字符 
	8. 学生状态(用数字表示,正常、休学、毕业...)

解:

create tbale student(
	id int,
	name varchar(10),
	gender char(1),
	birthday date,
	score double(5,2),
	email varchar(15),
	tel varchar(15),
	status tinyint
);

4. 删除表 (drop:删除)

删除表:

drop table 表名;

删除表时判断表是否存在:

drop table if exists 表名;

5.修改表(alter)

修改表名:

alter table 表名 rename to 新的表名;

	例子:将表名student改为stu
	alter table student rename to stu;

添加一列:

alter atble 表名 add 列名 数据类型;

	例子:给stu表添加列address,该字段类型是varchar(50)
	alter table stu add address varchar(50);

修改列的数据类型:

alter table 表名 modify 列名 新数据类型;
	
	例子:给stu表中的address字段的类型改为char(50)
	alter table stu modify address char(50);

修改列名和数据类型:

alter table 表名 change 列名 新列名 新数据类型;

	例子:将stu表中的address字段名改为addr,类型改为varchar(50);
	alter table stu change address addr varchar(50);

删除列:(有点特殊)

alter table 表名 drop 列名;

	例子:将stu表中的addr字段删除
	alter table stu drop addr;

二、DML 操作数据(对数据:增删改)

在这里插入图片描述

1. 添加数据(insert into)

1.1 给指定的列 添加数据(insert:插入)

insert into 表名(列名1,列名2...) values(1,值2...);

-- 例子:
-- 给指定的列添加数据
insert into stu(id , name) values(1,'张三');

1.2 给全部的列 添加数据

insert into 表名 values(1,值2...);

-- 例子
-- 给所有的列添加数据
insert into stu(id,name,sex,birthday,score,eamil,tel,status) values(1,'张三','男','2000-01-01',99.99,'ak@qq.com','12312312312',1)
dd
-- 简写 : 给所有列添加数据,列名的列表可以省略的
insert into stu (1,'张三','男','2000-01-01',99.99,'ak@qq.com','12312312312',1)
                 

1.3 批量添加数据

insert into 表名(列名1,列名2...) values(1,值2...)(1,值2...)(1,值2...)...;
insert into 表名 values(1,值2),(1,值2...)(1,值2...)..;

-- 例子
-- 批量添加数据
insert into stu values
	(1,'张三','男','2000-01-01',99.99,'ak@qq.com','12312312312',1),
	(1,'张三','男','2000-01-01',99.99,'ak@qq.com','12312312312',1),
	(1,'张三','男','2000-01-01',99.99,'ak@qq.com','12312312312',1);

2.修改数据(update)

update 表名 set 列名1=1, 列名2=2, ...  where 条件;

-- 注意:如果不加条件,则将所有数据都修改!

练习:
-- 将张三的性别改为女
update stu set sex='女' where name='张三';

-- 将李四的生日改为1999-12-12、分数改为99.99
update stu set birthday='1999-12-12', score=99.99 where name='张三';

-- 把班级的分数都全部改为60
update set set score=60;

3.删除数据(delete)

delete from 表名 where 条件;

练习:
-- 删除张三的记录
delete from stu where name='张三';

-- 删除所有数据
delete from stu;

三、DQL:操作数据

在这里插入图片描述

1.查询语法

  • 基础查询
  • 条件查询(where)
  • 分组查询(group by)
  • 排序查询(order by)
  • 分页查询(limit)
select
	字段列表
from 
	表名列表
where
	条件列表
group by
	分组列表
having
	分组后条件
order by
	排序字段
limit 
	分页限定

1.1 基础查询(select from)

  • 查询多个字段:
select 字段列表 from 表名;
select * from 表名; -- 查询所有数据

-- 练习
-- 查询name ,age 两列
select name,age from stu;

-- 查询所有数据
select * from stu;
  • 去除重复记录

    select distinct 字段列表 from 表名;
    
    -- 练习
    -- 查询地址,但是地址有很多重复的,要去重复
    select distinct address from stu;
    
  • 取别名

as

1.2 条件查询(** where)

select 字段列表 from 表名 where 条件列表;

条件列表可以用下面的运算符:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vP9LxQYD-1664074548060)(mysql.assets/image-20220714143633516.png)]

练习:
-- 查询年龄大于等于20岁的学员信息
select * from stu where age>=20;

-- 查询年龄大于等于20岁并且年龄小于等于30岁的学员信息
select * from stu where age between 20 and 30;

-- 查询年龄不等于18岁的学员信息
select * from stu !=18;

-- 查询年龄等于18岁 或者 年龄等于20岁 或者 年龄等于22岁 的学员信息
select * from stu where age age=18 or age=20 or age=22;
或者4 
select * from stu where age in(18,20,22);

-- 查询英语成绩为null的学员信息
select * from stu where english is null;   -- 而不是english = null

  • 模糊查询like

    _ : 代表单个字符 % : 代表任意字符(0~n)

-- 查询姓马的学生信息
select * from stu where name like '马%';

-- 查询第二个字是'花'的学生
select * from stu where name like '_花%';

-- 查询名字中包含'德'的学生
select * from stu where name like '%德%';

1.3 排序查询(order by)

select 字段列表 from 表名 order by 排序字段名1 排序方式, 排序字段名2 排序方式2 ...;

Asc :升序(默认)(不写排序方式,也是默认了)

Desc:降序

​ 注意:如果有多个排序条件,当前边的条件值一样时,才会根据第二条件进行排序

-- 练习
-- 查询学生信息,按照年龄升序排列
select * from stu order by age;

-- 查询学生信息,按照数学成绩降序排列
select * from stu order by math desc;

-- 查询学生信息,按照数学成绩降序排列,如果数学成绩一样,再按照英语成绩升序排列
select * from stu order by math desc, englis asc;

1.4 分组查询 group by

先得知道 聚合函数

在这里插入图片描述

语法:

select  聚合函数(列名)  from  表名;

注意:null值不参与 所有聚合函数运算

练习

-- 统计班级一共有多少个学生
select count(*) from stu;

-- 查询数学成绩的最高分
select max(math) from stu;

-- 查询数学成绩的最低分
select min(math) from stu;

-- 查询数学成绩的平均分
select avg(math) from stu;

-- 查询英语成绩的最低分
select min(english) from stu;  -- null值不参与查询

分组查询:

select  字段列表  from 表名 [where 分组前条件限定]  group by  分组字段名 [having 分组后条件过滤]; 

注意:分组之后,查询的字段为聚合函数和分组字段,查询其他字段无任何意义

练习:

-- 查询男同学和女同学各自的数学平均分
select   sex, avg(math)   from stu group by sex;

-- 查询男同学和女同学各自的数学平均分,以及各自人数
select   sex, avg(math), count(*) from stu group by sex;


-- 查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于70分的不参与分组
select   sex, avg(math), count(*) from stu where math>70 group by sex;

-- 查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于70分的不参与分组,分组之后人数大于2个的
select   sex, avg(math), count(*) from stu where math>70 group by sex 
having count(*)>2;

1.5 分页查询 limit

select 字段列表 from 表名 limit 起始索引,查询条目数

索引和数组一样,从0开始,第0个数,第1个数…

索引    id
0		1
1		2
2		3
3		4
4		5
5		6
6		7
7		8
8		9
-- 练习
-- 从0开始查询,查询3条数据
select * from stu limt 0,3;  -- 0号索引 往后查3位数  结果是1 2 3

-- 每页显示3条数据,查询第1页数据
select * from stu limt 0,3;   -- 0号索引 往后查3位数  结果是1 2 3

-- 每页显示3条数据,查询第2页数据  
select * from stu limt 3,3;  -- 3号索引 往后查3位数  结果是4 5 6

-- 每页显示3条数据,查询第3页数据
select * from stu limt 6,3; -- 6号索引 往后查3位数  结果是7 8 9

由此推出:

*起始索引=(当前页面 - 1)每页要显示的条数

SQL面试50题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jBrmAzs9-1664074548063)(mysql.assets/image-20220714143815519.png)]

53道题 目录

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PwOgislL-1664074548063)(mysql.assets/image-20220714151404538.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9LYVZ2ag-1664074548064)(mysql.assets/image-20220714144922086.png)]

其中重点为:

1 / 2 / 5 / 6 / 7 / 10 / 11 / 12 / 13

15 / 17 / 18 / 19 / 22 / 23 / 25

31 / 35 / 36 / 40 / 41 / 42 / 45 / 46

超级重点 18和23、 22和25 、 41、46

为了方便学习,我将50道面试题进行了分类

1. 简单查询

###

查询姓“猴”的学生名单

  1. 查询 姓 “孟” 老师的个数
select count(t_name) from teacher where t_name like '孟%';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9OcsfzaJ-1664074548065)(mysql.assets/image-20220715165825045.png)]

2. 汇总分析聚合函数、group by和where的相爱相杀

select 字段列表 from 表名 [where 分组前条件限定] group 分组字段名 [having 分组后条件过滤]
  1. 聚合函数sum / avg / count / max / min 经常与好基友group by搭配使用

在这里插入图片描述

  1. 在使用group by时,select后面只能放
  • 常数(如数字/字符/时间)
  • 聚合函数
  • 聚合键(也就是group by后面的列名);

​ 因此,在使用group by时,千万不要在select后面放聚合键以外的列名!

  1. where函数后面不能直接使用聚合函数!

  2. where having 区别:

    where分组之前进行限定,不满足where条件的,则不参与分组

    having分组之后对结果进行过滤

在这里插入图片描述

  1. 查询 课程编号为 “0002” 的总成绩
-- 分解
1.查询成绩:              select * from score;
2.查询课程编号为0002的成绩: select * from score where c_id='002';
3.查询课程编号为0002的总成绩:select sum(s_score) from score where c_id='0002';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fkGHL2Vh-1664074548065)(mysql.assets/image-20220715171710069.png)]

  1. 查询 男生、女生人数
-- 分解
1.查询总人数:select count(*) from student;
2.查询男生、女生的总人数:select sex,count(*) from student group by sex;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k3x5eAOs-1664074548066)(mysql.assets/image-20220715171643996.png)]

  1. 查询各科的最低分和最低分
-- 分解
1.查询分数:select * from score;
2.查询各科的分数:select c_id from score group by c_id;
3.查询各科的分数的最最低分,最低分:select c_id,  max(s_score), min(s_score) from score group by c_id;

4. 查询 课程编号为02(数学) 的总成绩【聚合函数】
select Cno,sum(score) from sc group by Cno having Cno='02';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hRf5bjOs-1664074548067)(mysql.assets/image-20220714155040748.png)]

5. 查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列【聚合函数】
select Cno,avg(score) as avg_score from sc 
group by Cno
order by avg_score desc,cno;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bjvxRRSo-1664074548068)(mysql.assets/image-20220714160953547.png)]

6. 求每门课程的学生人数 【聚合函数】
select Cno,count(Sno) from student group by Sno;
7. 查询各科成绩最高和最低的分, 以如下的形式显示:课程号,最高分,最低分
select 
c_id,
max(s_score) as 最高分,
min(s_score) as 最低分 
from score 
group by c_id

扩展 (超级重点)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y8knMNW2-1664074548069)(mysql.assets/image-20220720145506138.png)]

-- 查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
-- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90 

-- 第一步:聚合计算(用到了case when) 
-- 及格率=及格的人数/总人数
-- 解读:第7句,case when:当score表中的分数有一个及格,记为1,把分数sum就得到及格人数
select 
c_id,
count(*) as 选修人数,
max(s_score) as 最高分,
min(s_score) as 最低分,
avg(s_score) as 平均分,
sum(case when s_score>=60 then 1 else 0 end)/count(*) as 及格率,
sum(case when s_score>=70 and s_score<80 then 1 else 0 end)/count(*) as 中等率,  
sum(case when s_score>=80 and s_score<90 then 1 else 0 end)/count(*) as 优良率,
sum(case when s_score>=90 then 1 else 0 end)/count(*) as 优秀率
from score
group by c_id;

-- 第二步:排序 (只在最后一行追加了一句)
select 
c_id,
count(*) as 选修人数,
max(s_score) as 最高分,
min(s_score) as 最低分,
avg(s_score) as 平均分,
sum(case when s_score>=60 then 1 else 0 end)/count(*) as 及格率,
sum(case when s_score>=70 and s_score<80 then 1 else 0 end)/count(*) as 中等率,  
sum(case when s_score>=80 and s_score<90 then 1 else 0 end)/count(*) as 优良率,
sum(case when s_score>=90 then 1 else 0 end)/count(*) as 优秀率
from score
group by c_id
order by count(*) desc,c_id asc;

-- 第三步: 显示课程名字,即(成绩表)要关联 课表表
select 
x.* , cname  -- 要显示x中的所有结果 和 y表中的cname课程名字
from(第二步的所有结果) x  -- 把第二部的成绩表取别名为x
left join course y -- 把course表取别名为y
on x.c_id = y.c_id; -- 通过x表的c_id 与 y表的c_id 来建立连接

———>
最后答案:
select 
x.* , c_name  -- 要显示x中的所有结果 和 y表中的cname课程名字
from(select 
c_id,
count(*) as 选修人数,
max(s_score) as 最高分,
min(s_score) as 最低分,
avg(s_score) as 平均分,
sum(case when s_score>=60 then 1 else 0 end)/count(*) as 及格率,
sum(case when s_score>=70 and s_score<80 then 1 else 0 end)/count(*) as 中等率,  
sum(case when s_score>=80 and s_score<90 then 1 else 0 end)/count(*) as 优良率,
sum(case when s_score>=90 then 1 else 0 end)/count(*) as 优秀率
from score
group by c_id
order by count(*) desc,c_id asc) x  -- 把第二部的成绩表取别名为x
left join course y -- 把course表取别名为y
on x.c_id = y.c_id; -- 通过x表的c_id 与 y表的c_id 来建立连接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ki7chqii-1664074548069)(mysql.assets/image-20220716162213521.png)]

8 . 查询每门课程被选修的学生数
select c_id,count(s_id)
from score
group by c_id;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5fmMBzev-1664074548070)(mysql.assets/image-20220716162351249.png)]

9. 查询同名同姓的学生名单并统计同名人数
-- 查询同名同姓学生名单并统计同名人数
select 
s_name,count(*) as 同名同姓
from student
group by s_name
having count(*)>=2;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1YxaEwUQ-1664074548071)(mysql.assets/image-20220717150238474.png)]

10. 查询不及格的课程 并 按课程号从大到小排列
select c_id
from student
where s_score<60
order by c_id desc;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ylHvgPlD-1664074548072)(mysql.assets/image-20220717151944635.png)]

11. 查询每门课程的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列
select c_id , avg(s_score) as 平均分
from score
group by c_id
order by 平均分 asc , c_id desc;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZcqUnTtq-1664074548073)(mysql.assets/image-20220717153524079.png)]

12. 检索课程编号为“0002”且分数小于60的学生学号,结果按分数降序排列
select s_id
from score 
where c_id='0002' and s_score<60
oreder by s_score desc;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ue98T7LK-1664074548073)(mysql.assets/image-20220717154511854.png)]

13 .统计每门课程的学生选修人数(超过2人的课程才统计)

要求: 输出课程号和选修人数,查询结果按人数降序排序,若人数相同,按课程号升序排序

select c_id ,count(s_id) as 选修人数
from score 
group by c_id
having count(s_id)>2
order by 选修人数 desc , c_id asc;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v1LenOIt-1664074548074)(mysql.assets/image-20220718164542725.png)]

14 . 查询两门以上不及格课程的同学的学号 及其 平均成绩
select  s_id , avg(s_score)
from score
where s_socre<60
group by s_id
having count(c_id)>2;

​                        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Obv5nWJp-1664074548075)(mysql.assets/image-20220718163301474.png)]

汇总分析:

15. 查询学生的总成绩 并 进行排名
select s_id , sum(s_score) as 总成绩
from score
group by s_id
oreder by sum(s_score) asc;

​                               [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ewbldOcQ-1664074548075)(mysql.assets/image-20220718163819437.png)]

16. 查询平均成绩大于60分的学生的学号和平均成绩
select s_id, avg(s_score)
from score
group by s_id
having avg(s_score)>60;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-smYR1Vgi-1664074548076)(mysql.assets/image-20220718164310000.png)]

复杂查询:

17. 查询所有课程成绩小于60分学生的学号、姓名
-- 第1步,查询小于60分的学生出来
select s_id
from score
where s_score<6;  -- 得出小于60分的学生的表a

-- 第2步,查询 学生表中 小于60分 的名单
select s_id , s_name
from student
where s_id in(小于60分的学生的表a);
-- 即
select s_id , s_name
from student
where s_id in(
	select s_id
	from score
	where s_score<6    
);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NZ0McA2t-1664074548077)(mysql.assets/image-20220718173344357.png)]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值