必备SQL语句
SQL程序语言有四种类型,对数据库的基本操作都属于这四类,它们分别为;数据定义语言(DDL)、数据查询语言(DQL)、数据操纵语言(DML)、数据控制语言(DCL)
类型分类
DDL
主要语法有
CREATE、ALTER、DROP和TRUNCATE
1 | CREATE TABLE 表名称 |
DQL
主要语法是
SELECT
1 | SELECT 列名称 FROM 表名称 |
DML
主要语法有
INSERT、UPDATE、DELETE
1 | UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值 |
DCL
主要语法有
GRANT,REVOKE,COMMIT,ROLLBACK
1 | GRANT 权限1, … , 权限n ON 数据库.对象 TO 用户名; |
而基于上面的语法可以有很多操作,练习基础表,可以建表敲敲代码试试看
1 | CREATE TABLE depart( |
1 | INSERT INTO `depart` VALUES (1, '开发'); |
条件
1 | select * from info where id >1; |
通配符
一般用于模糊查找
1 | -- % 表示匹配任意字符 |
注意:数量少,数据量大的搜索
映射
1 | select * from info; |
1 | # 注意效率很低 |
1 | select |
排序
1 | select * from info order by age desc; -- 倒数 |
取部分
1 | select * from info limit 5; -- 获取前5条数据 |
分组
1 | select 字段名 from 表名 group by 字段名; |
1 | select age,max(id),min(id),sum(id),count(id),avg(id) from info group by age; |
1 | select age,name from info group by age; -- 不建议 因为同一个年龄下有多个姓名数据,所以会报错 |
1 | select age ,count(id) from info group by age having count(id) > 2; -- 聚合条件 |
1 | -- 到目前为止SQL顺序 |
1 | select age,count(id) from info where id >2 group by age having count(id)>1 order by age desc limit 1; |
连表
多个表可以连接起来查询
外连接
1 | 主表 left outer join 从表 on 主表.x =从表.id |
1 | select * from info left outer join depart on info.depart_id=depart.id; -- 向外表进行左连接,表示这个表为主表.连接条件为depart_id |
1 | 从表 right outer join 主表 on主表.字段=从表.字段 |
1 | select * from depart right outer join info on depart.id=info.depart_id; |
主表在左从表在右
为了更加直接的查看效果,我们分别在depart表和info中额外插入一条数据。
1 | insert into depart(title) values("安全"); |
左外连接
右外连接
简写
1 | select * from depart left join info on ... |
内连接
有对应关系才显示,没有就忽略掉
1 | select * from info inner join depart on info.depart_id=depart.id; |
1 | 到目前位置的SQL执行顺序 |
联合
1 | select id,title from depart |
1 | select id from depart |
1 | select id from depart |
表关系
- 单表
- 一对多
- 多对多
外键约束
1 | CREATE table info( |
如果表已经建 好了
1 | alter table info add constraint fk_info_depart foreign key info(depart_id) references depart(id); |
删除外键
1 | alter table info drop foreign key fk_info_depart; |
外键条件
在我们使用外键的时候,应该遵循如下条件:
外键要存在,首先必须保证表的引擎是 InnoDB(默认的存储引擎),如果不是 InnoDB 存储引擎,那么外键可以创建成功,但没有约束作用;
外键字段的字段类型(列类型),必须与父表的主键类型完全一致;
每张表中的外键名称不能重复;
增加外键的字段,如果数据已经存在,那么要保证数据与父表中的主键对应。
如果外键约束模式选择SET NULL ,那么字段必须允许为NULL,否则出现Cannot add foreign key constraint。
在以后项目开发时,设计表结构及其关系的是一个非常重要的技能。一般项目开始开发的步骤:
需求调研
设计数据库表结构(根据需求)
项目开发(写代码)
大量的工作应该放在前2个步骤,前期的设计完成之后,后续的功能代码开发就比较简单了。
授权
之前我们无论是基于Python代码还是自带客户端去连接MySQL时,均使用的是root账户,拥有对MySQL数据库操作的所有权限。
如果有多个程序的数据库都放在同一个MySQL中,如果程序都用root账户就存在风险了。
这种情况怎么办呢?
在MySQL中支持创建账户,并给账户分配权限,例如:只拥有数据库A操作的权限、只拥有数据库B中某些表的权限、只拥有数据库B中某些表的读权限等。
用户管理
在MySQL的默认数据库mysql
中的user
表中存储着所有的账户信息(含账户、权限等)。
1 | mysql> show databases; |
1 | desc mysql.`user` |
创建和删除用户
1 | create user '用户名'@'连接者的IP地址' identified by '密码'; |
1 | create user bobo@127.0.0.1 identified by 'root'; |
修改用户
1 | rename user '用户名'@'连接者ip地址' identified by '密码'; |
1 | rename user bobo@127.0.0.1 to bobo@localhost; |
修改密码(mysql==5.7)
1 | set password for '用户名'@'ip地址'=Password('新密码'); |
1 | set password for 'bobo'@'127.0.0.1'=Password('123') |
授权管理
创建好用户后就可以进行授权了
授权
1
grant 权限 on 数据库.表 to '用户'@'ip地址'
1
2
3
4
5
6
7
8
9
10
11
12
13grant all privileges on *.* TO 'bobo'@'localhost';
-- 用户bobo且在本地时拥有所有权限
grant all privileges on django_test.* TO 'bobo'@'localhost';
-- 用户bobo且在本地时拥有django_test库所有权限
grant all privileges on django_test.info to 'bobo'@'localhost';
-- 用户bobo且在本地时拥有django_test库的info表所有权限
grant select on django_test.info To 'bobo'@'localhost';
-- 用户bobo且在本地时拥有django_test库select权限
grant select,insert on django_test.* to 'bobo'@'localhost';
-- 用户bobo且在本地时拥有django_test库select,insert权限
-- 注意flush privileges; 将数据读取到内存,从而立即生效对于权限
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30all privileges 除grant外的所有权限
select 仅查权限
select,insert 查和插入权限
...
usage 无访问权限
alter 使用alter table
alter routine 使用alter procedure和drop procedure
create 使用create table
create routine 使用create procedure
create temporary tables 使用create temporary tables
create user 使用create user、drop user、rename user和revoke all privileges
create view 使用create view
delete 使用delete
drop 使用drop table
execute 使用ca11和存储过程
file 使用select into outfile和load data infile
grant option 使用grant和revoke
index 使用index
insert 使用insert
lock tables 使用lock tab1e
process 使用show ful1 processlist
select 使用select
show databases 使用show databases
show view 使用show view
update 使用update
reload 使用f1ush
shutdown 使用mysqladmin shutdown(关闭MySQL)
super 使用change master、kill、logs、purge、master和set global。还允许mysqladmin调试登陆
replication client 服务器位置的访问
replication slave 由复制从属使用对数据库和表
1
2
3
4数据库名 数据库中的所有
数据库.表名 指定数据库中的某张表
数据库.存储过程名 指定数据库中的存储过程
*。*
查看授权
1
show grants for '用户'@'IP地址'
1
show grants for 'bobo'@'localhost';
取消权限
1
revoke 权限 on数据库.表 from '用户'@'IP地址';
1
revoke all privileges on django_test.info.* from 'bobo'@'localhost';
一般情况下,在很多的正规公司,数据库都是由DBA来统一进行管理,DBA为每个项目的数据库创建用户,并赋予相关的权限。
数据库的导入和导出
根据上图创建 数据库&表结构 并录入数据(可以自行创造数据)
1 | create database test default charset utf8 collate utf8_general_ci; |
利用导入数据库命令:
导入
1
mysql -u root -p test <
1
mysql -uroot < /home/project/init-MySql.sql
导出
1
2
3
4
5
6# 数据+结构
mysqldump -u root -p test > backup.sql
mysqldump -u root -p database_name >/home/project/init-MySql.sql
# 结构
mysqldump -u root -p -d test > backup.sql
练习题
1 | 1.根据上图创建数据库&表结构并录入数据(可以自行创造数据) |
注意下面为答案
个人写的可能有些问题
1-10
1.根据上图创建数据库&表结构并录入数据(可以自行创造数据)
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- 创建数据库 |
2.创建用户test_root并赋予此数据库的所有权限。
警告此处为个人本题答案仅供参考,非唯一答案
1 | create user 'test_user'@'127.0.0.1' identified by 'root'; |
注意要是链接写的是127.0.0.1 实际上也是本地,但是还是得写127.0.0.1而不能写localhost 否则1045
3.查询姓“李"的老师的个数。
警告此处为个人本题答案仅供参考,非唯一答案
1 | select count(tid) from teacher where tname like '李%'; |
4.查询姓“张"的学生名单。
警告此处为个人本题答案仅供参考,非唯一答案
1 | SELECT * from student WHERE sname like "张%"; |
5.查询男生、女生的人数。
警告此处为个人本题答案仅供参考,非唯一答案
1 | SELECT gender,count(1) from student GROUP BY gender ;-- count在这里只是一个聚合函数里面写1还是0都行 |
6.查询同名同姓学生名单,并统计同名人数。icon:hashtag
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- 返回同名同姓的姓名和人数 |
综合整的花活
1 | -- 综合 整的花活 |
7.查询“三年二班”的所有学生。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
8.查询每个班级的班级名称、班级人数。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- 显示班级id不显示班级名 |
9.查询成绩小于60分的同学的学号、姓名、成绩、课程名称。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
10.查询选修了"生物课"的所有学生ID、学生姓名、成绩。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
11-20
11.查询选修了"生物课”且分数低于60的的所有学生ID、学生姓名、成绩。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
12.查询所有同学的学号、姓名、选课数、总成绩。
1 | -- (1) |
13.查询各科被选修的学生数。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- 核心 |
14.查询各科成绩的总分、最高分、最低分,显示:课程ID、课程名称、总分、最高分、最低分。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
15.查询各科成绩的平均分,显示:课程ID、课程名称、平均分。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
16.查询各科成绩的平均分,显示:课程ID、课程名称、平均分(按平均分从大到小排序)。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
注14-16题写的都是满足所有的需求,即句子一样。看题目删去
17.查询各科成绩的平均分和及格率,显示:课程ID、课程名称、平均分、及格率。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
18.查询平均成绩大于60的所有学生的学号、平均成绩。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
19.查询平均成绩大于85的所有学生的学号、平均成绩、姓名。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (核心) |
20.查询“三年二班”每个学生的学号、姓名、总成绩、平均成绩。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
21-30
21.查询各个班级的班级名称、总成绩、平均成绩、及格率(按平均成绩从大到小排序)
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
22.查询学过“朱元璋”老师课的同学的学号、姓名。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
23.查询没学过“朱元璋”老师课的同学的学号、姓名。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- 有选课的 |
24.查询选修“朱棣”老师所授课程的学生中,成绩最高的学生姓名及其成绩(不考虑并列)。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
25.查询选修“朱棣”老师所授课程的学生中,成绩最高的学生姓名及其成绩(考虑并列)
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
26.查询只选修了一门课程的全部学生的学号、姓名
警告此处为个人本题答案仅供参考,非唯一答案
1 | SELECT |
27.查询至少选修两门课程的学生学号、学生姓名、选修课程数量。
警告此处为个人本题答案仅供参考,非唯一答案
1 | SELECT |
28.查询两门及以上不及格的同学的学号、学生姓名、选修课程数量。
警告此处为个人本题答案仅供参考,非唯一答案
1 | SELECT |
29.查询选修了所有课程的学生的学号、姓名。
警告此处为个人本题答案仅供参考,非唯一答案
1 | SELECT |
30.查询未选修所有课程的学生的学号、姓名。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
31-40
31.查询所有学生都选修了的课程的课程号、课程名。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- 可能有些没有选的,排除 |
32.查询选修“生物°和“物理”课程的所有学生学号、姓名。
警告此处为个人本题答案仅供参考,非唯一答案
1 | SELECT |
33.查询至少有一们课与学号为“1的学生所选的裸程相同的其他学生学号和姓名
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
34.查询与学号为“2”的同学选修的课程完全相同的具地学生学号和姓名。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) |
35.查询生物”课程比”物理”课程成绩高的所有学生的学号。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- 没有选择目标课程不做考虑 |
36.*查询每门课程成绩最好的前3名(不专虑成绩并列情况)。
警告此处为个人本题答案仅供参考,非唯一答案
1 | -- (1) 前三信息(并列也取前三个) |
37.*查询每门课程成绩最好的前3名(考虑成绩并列情况)。
警告此处为个人本题答案仅供参考,非唯一答案
1 | SELECT s1.course_id, s1.student_id, s1.number |
38.创建一个表sc,然后将score表中所有数据插入到sc表中。
警告此处为个人本题答案仅供参考,非唯一答案(step1)
1 | CREATE TABLE sc( |
警告此处为个人本题答案仅供参考,非唯一答案(step2)
1 | insert into sc select * from score; |
39.向score表中插入一些记录,这些记录要求符合以下条件:
- 学生ID为:没上过课程D为“2”课程的学生的学号:
- 课程ID为:2
- 成绩为:80
警告此处为个人本题答案仅供参考,非唯一答案(step1)
1 | SELECT student.sid,2,80 FROM student JOIN score on student.sid=score.student_id GROUP BY score.student_id HAVING MAX(CASE WHEN score.course_id = 2 THEN score.number END) IS NULL |
这里使用了MAX函数和CASE表达式来判断学生是否选了课程2。如果学生选了课程2,那么MAX函数会返回该课程的最高分数;如果学生没有选课程2,那么MAX函数会返回NULL。通过判断MAX函数的返回值是否为NULL,就可以筛选出没有选课程2的学生了。
警告此处为个人本题答案仅供参考,非唯一答案(step2)
1 | insert into sc (student_id,course_id,number) SELECT student.sid,2,80 FROM student JOIN score on student.sid=score.student_id GROUP BY score.student_id HAVING MAX(CASE WHEN score.course_id = 2 THEN score.number END) IS NULL |
40.向score表中插人些记录,这些记录要求符合以下条件:icon:hashtag
- 学生ID为:学过课程ID为“5”课程的学生的学号。
- 课程ID为:2。(我知道根据我的数据这个同学已经学历这个课程)
- 成绩为:课程ID为3的最高分。
警告此处为个人本题答案仅供参考,非唯一答案
1 | INSERT INTO score (student_id, course_id, number) |
总结
练习题做了挺久的,至于多久呢?我也不好意思说,以免你说我太菜了(扶额
好吧,最近可能要开启爆更模式咯。喜欢我的文章麻烦点个有用或者赞同或者收藏之类的呗(^_^)。有什么问题和疑问可以在评论区留盐
同样在知乎发布: