Day32
DDL
DDL(数据定义语言):操作数据库、表、字段的语言
# 操作库 -------------------------------------------------------- # 使用库 USE DATABASE 2042javaee; # 创建库 CREATE DATABASE 2042javaee; # 删除库 DROP DATABASE 2042javaee; # 查询所有库 SHOW DATABASES; # 操作表 -------------------------------------------------------- # 查询所有表 SHOW TABLES; # 创建表 # VARCHAR(32):最多可以存储32个字符长度的字符串 # FLOAT(8,2):最多存储长度为8的数字,其中2位为小数位 CREATE TABLE s_student( name VARCHAR(64), s_sex VARCHAR(32), age INT(3), salary FLOAT(8,2), s_course VARCHAR(64) ) # 修改表名 ALTER TABLE s_student RENAME student; # 删除表 DROP TABLE student; # 操作字段 -------------------------------------------------------- # 添加字段 ALTER TABLE student ADD xxx VARCHAR(32); # 删除字段 ALTER TABLE student DROP xxx; # 修改字段类型 ALTER TABLE student MODIFY name VARCHAR(32); # 修改字段名 ALTER TABLE student CHANGE s_sex sex VARCHAR(32); # 修改字段名 + 类型 ALTER TABLE student CHANGE s_course course VARCHAR(32); # 查询字段信息 DESC student; # 查询创建表信息 # 注意:MySQL会将sql命令有一定的优化 SHOW CREATE TABLE student; -- CREATE TABLE `student` ( -- `name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL, -- `sex` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL, -- `age` int DEFAULT NULL, -- `salary` float(8,2) DEFAULT NULL, -- `course` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL -- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci --
DML
DML(数据操作语言):针对数据增删查改的语言
DQL:DDL中特指针对数据查询的语言
# 创建表 # 注意:一张表必须有且只有一个主键 # 理解主键:数据行的唯一标识,主键字段上的数据不允许重复且不能为null # PRIMARY KEY - 主键 # auto_increment - 自动增长 CREATE TABLE student( id INT(3) PRIMARY KEY auto_increment, name VARCHAR(32), sex VARCHAR(32), salary FLOAT(8,2), age INT(3), course VARCHAR(32) ) # 添加数据 ---------------------------------------------------------------------------- # 添加数据 - 方式一 INSERT INTO student VALUES (1,"张三","男",8000,25,"Java"); # 添加数据 - 方式二 INSERT INTO student VALUES(2,"李四","男",9000,21,"Java"),(3,"王五","女",6000,20,"Python"); # 添加数据 - 方式三 INSERT INTO student (name,sex,salary,age,course) VALUES ("华晨宇","男",8000,18,"Java"); INSERT INTO student (name,sex,salary,age,course) VALUES ("刘德华","男",7000,22,"HTML"); INSERT INTO student (name,sex,salary,age,course) VALUES ("周华健","男",9000,31,"HTML"); INSERT INTO student (name,sex,salary,age,course) VALUES ("欧阳震华","男",8000,30,"HTML"); INSERT INTO student (name,sex,salary,age,course) VALUES ("李华","男",3000,18,"Java"); # 删除数据 ---------------------------------------------------------------------------- # 清空表数据 - 方式一:删除后,再次添加数据id从1开始 TRUNCATE student; # 清空表数据 - 方式二:删除后,再次添加数据id从上次开始。推荐使用,因为数据恢复后主键不会冲突 DELETE FROM student; # 单条件删除 DELETE FROM student WHERE id=2; # 多条件删除 # OR - 或 # AND - 与 DELETE FROM student WHERE id=1 OR sex="女"; DELETE FROM student WHERE sex="男" AND course="HTML"; DELETE FROM student WHERE course IN ("Java","HTML"); # 修改数据 ---------------------------------------------------------------------------- # 修改单条件数据 UPDATE student SET name="赵六" WHERE id=3; # 修改多条件数据 UPDATE student SET salary=10000 WHERE course="Java" OR salary<=5000; UPDATE student SET salary=9000 WHERE sex = "男" AND id>3; UPDATE student SET salary=20000 WHERE course IN ("Java","Python"); # 修改多条数据 UPDATE student SET sex="女",id=1 WHERE name="张三"; # 查询数据 ---------------------------------------------------------------------------- # 查询所有字段 SELECT * FROM student; # 查询指定字段 SELECT name,sex,course from student; # 查询指定字段 + 别名 SELECT name AS "姓名",sex AS "性别",salary AS "薪水" FROM student; # 去重查询 # 需求:查询学科 SELECT DISTINCT course FROM student; # 单字段排序查询 # ORDER BY - 排序 # ASC - 升序 # DESC - 降序 # 需求:年龄排升序 SELECT * FROM student ORDER BY age ASC; # 需求:工资排降序 SELECT * FROM student ORDER BY salary DESC; # 多字段排序查询 # 需求:年龄排升序,年龄一致工资排降序 SELECT * FROM student ORDER BY age ASC,salary DESC; # 单条件查询 SELECT * FROM student WHERE age<25; # 多条件查询 SELECT * FROM student WHERE sex="男" AND salary>6000; SELECT * FROM student WHERE age>22 OR salary>6000; SELECT * FROM student WHERE course IN ("Java","HTML"); # 模糊查询 # % - 没有或多个任意字符 # _ - 一个任意字符 # 需求:查询出姓名中带'华'字的数据 SELECT * FROM student WHERE name LIKE "%华%"; # 需求:查询出姓名中第四个带'华'字的数据 SELECT * FROM student WHERE name LIKE "___华"; # 限制排序 # 需求:查询出工资最高的学生信息 SELECT * FROM student ORDER BY salary DESC LIMIT 1; # 分页查询 # SELECT * FROM student LIMIT 偏移量,数据条数; SELECT * FROM student LIMIT 0,2 # 第1页 SELECT * FROM student LIMIT 2,2 # 第1页# 第2页 SELECT * FROM student LIMIT 4,2 # 第1页# 第3页 # 分页公式:SELECT * FROM student LIMIT (页数-1)*数据条数,数据条数; # 聚合查询(统计类函数查询) # 需求:查询最高工资 SELECT MAX(salary) FROM student; # 需求:查询最低工资 SELECT MIN(salary) FROM student; # 需求:查询工资总和 SELECT SUM(salary) FROM student; # 需求:查询平均工资 + 保留小数点后两位 SELECT AVG(salary) FROM student; SELECT ROUND(AVG(salary),2) FROM student; # 需求:查询学生个数 SELECT COUNT(id) FROM student; # 子查询 # 需求:查询出工资最高的学生信息 SELECT * FROM student WHERE salary = (SELECT MAX(salary) FROM student); # 分组查询 # 需求:查询出各个学科的平均工资 SELECT AVG(salary),course FROM student GROUP BY course; # 分组过滤查询 # 需求:查询出平均工资大于5000的学科 SELECT course,AVG(salary) FROM student GROUP BY course HAVING AVG(salary)>5000;
难点:多表联合查询
# 多表联合查询 -- 一对多的关系 # 创建场景 ------------------------------------------------------------------------------------------------- # 创建老师表,并添加数据 CREATE TABLE teacher( id INT(3) PRIMARY KEY auto_increment, name VARCHAR(32) ) INSERT INTO teacher(name) VALUES("何老师"); INSERT INTO teacher(name) VALUES("仓老师"); INSERT INTO teacher(name) VALUES("波老师"); # 创建学生表,并添加数据 CREATE TABLE student( id INT(3) PRIMARY KEY auto_increment, name VARCHAR(32), t_id INT(3) ) INSERT INTO student(name,t_id) VALUES("张三",1); INSERT INTO student(name,t_id) VALUES("李四",1); INSERT INTO student(name,t_id) VALUES("王五",2); INSERT INTO student(name,t_id) VALUES("赵六",2); INSERT INTO student(name,t_id) VALUES("李华",2); INSERT INTO student(name) VALUES("小明"); # 内连接 ------------------------------------------------------------------------------------------------- # 理解:查询出多张表有联系的数据 # 方式一 SELECT s.name,t.name FROM student s,teacher t WHERE s.t_id= t.id; # 方式二 SELECT s.name,t.name FROM student s INNER JOIN teacher t ON s.t_id=t.id; # 外连接 ------------------------------------------------------------------------------------------------- # 左连接 # 理解:查询出左边所有表里的数据 SELECT s.name,t.name FROM student s LEFT JOIN teacher t ON s.t_id = t.id; # 右链接 # 理解:查询出右边所有表里的数据 SELECT s.name,t.name FROM student s RIGHT JOIN teacher t ON s.t_id = t.id; # 全连接 ------------------------------------------------------------------------------------------------- # 理解:查询出多张表里所有的数据(不管有没有联系的数据) # 注意:MySQL没有全连接的命令,MySQL中全连接的实现就是合并查询结果 + 去重 # 合并查询结果 SELECT s.name,t.name FROM student s LEFT JOIN teacher t ON s.t_id = t.id UNION ALL SELECT s.name,t.name FROM student s RIGHT JOIN teacher t ON s.t_id = t.id; # 合并查询结果 + 去重 SELECT s.name,t.name FROM student s LEFT JOIN teacher t ON s.t_id = t.id UNION SELECT s.name,t.name FROM student s RIGHT JOIN teacher t ON s.t_id = t.id; # 多表联合查询 -- 多对多的关系 # 注意:多对多的关系必须有中间表 # 创建场景 ------------------------------------------------------------------------------------------------- # 创建学生表,并添加数据 CREATE TABLE student( id INT(3) PRIMARY KEY auto_increment, name VARCHAR(32) ) INSERT INTO student(name) VALUES('张三'); INSERT INTO student(name) VALUES('李四'); INSERT INTO student(name) VALUES('王五'); # 创建学科表,并添加数据 CREATE TABLE course( id INT(3) PRIMARY KEY auto_increment, name VARCHAR(32) ) INSERT INTO course(name) VALUES('语文'); INSERT INTO course(name) VALUES('数学'); INSERT INTO course(name) VALUES('英语'); # 创建成绩表,并添加数据 CREATE TABLE scores( id INT(3) PRIMARY KEY auto_increment, s_id INT(3), c_id INT(3), score FLOAT(4,1) ) INSERT INTO scores(s_id,c_id,score) VALUES(1,1,90); INSERT INTO scores(s_id,c_id,score) VALUES(1,2,93); INSERT INTO scores(s_id,c_id,score) VALUES(1,3,91); INSERT INTO scores(s_id,c_id,score) VALUES(2,1,99); INSERT INTO scores(s_id,c_id,score) VALUES(2,2,98); INSERT INTO scores(s_id,c_id,score) VALUES(2,3,97); INSERT INTO scores(s_id,c_id,score) VALUES(3,1,94); INSERT INTO scores(s_id,c_id,score) VALUES(3,2,95); INSERT INTO scores(s_id,c_id,score) VALUES(3,3,96); SELECT stu.name,cou.name,sco.score FROM student stu INNER JOIN course cou INNER JOIN scores sco ON sco.s_id=stu.id AND sco.c_id=cou.id; # 需求:查询出每个学生的平均成绩(学生姓名,平均分) SELECT stu.name,AVG(sco.score) FROM student stu INNER JOIN scores sco ON sco.s_id=stu.id GROUP BY stu.name; # 需求:查询出每个学生的最好成绩(学生姓名,最好学科,最好成绩) SELECT stu.name,cou.name,sco.score FROM scores sco INNER JOIN (SELECT sco.s_id,max(sco.score) AS 'maxScore' FROM scores sco GROUP BY sco.s_id) xx INNER JOIN student stu INNER JOIN course cou ON sco.score =xx.maxScore AND sco.s_id=xx.s_id AND sco.s_id=stu.id AND sco.c_id = cou.id;
DCL
DCL(数据控制语言):开子账号并设置权限
# 创建子账号 create user 'zs'@'localhost' identified by"123456"; # 添加权限 grant select,insert on 2402javaee.* to 'zs'@'localhost'; # 删除权限 revoke insert on 2402javaee.* from 'zs'@'localhost'; # 删除子账号 drop user 'zs'@'localhost';
练习
CREATE TABLE student( id INT(3) PRIMARY KEY auto_increment, name VARCHAR(32), birth VARCHAR(32), sex VARCHAR(32) ) CREATE TABLE teacher( id INT(3) PRIMARY KEY auto_increment, name VARCHAR(32) ) CREATE TABLE course( id INT(3) PRIMARY KEY auto_increment, name VARCHAR(32), t_id INT(3) ) CREATE TABLE score( id INT(3) PRIMARY KEY auto_increment, s_id INT(3), c_id INT(3), score INT(3) ) insert into student(name,birth,sex) values('aaa' , '1998-01-01' , '男'); insert into student(name,birth,sex) values('bbb' , '2001-12-21' , '男'); insert into student(name,birth,sex) values('ccc' , '1999-05-20' , '男'); insert into student(name,birth,sex) values('ddd' , '1998-08-06' , '男'); insert into student(name,birth,sex) values('eee' , '1999-12-01' , '女'); insert into student(name,birth,sex) values('fff' , '1998-03-01' , '女'); insert into student(name,birth,sex) values('ggg' , '2001-07-01' , '女'); insert into student(name,birth,sex) values('hhh' , '2000-01-20' , '女'); insert into teacher(name) values('何'); insert into teacher(name) values('仓'); insert into teacher(name) values('波多'); insert into teacher(name) values('波波'); insert into teacher(name) values('波波'); insert into course(name,t_id) values('语文' , 2); insert into course(name,t_id) values('数学' , 1); insert into course(name,t_id) values('英语' , 3); insert into score(s_id,c_id,score) values(1 , 1 , 80); insert into score(s_id,c_id,score) values(1 , 2 , 90); insert into score(s_id,c_id,score) values(1 , 3 , 99); insert into score(s_id,c_id,score) values(2 , 1 , 70); insert into score(s_id,c_id,score) values(2 , 2 , 60); insert into score(s_id,c_id,score) values(2 , 3 , 80); insert into score(s_id,c_id,score) values(3 , 1 , 80); insert into score(s_id,c_id,score) values(3 , 2 , 80); insert into score(s_id,c_id,score) values(3 , 3 , 80); insert into score(s_id,c_id,score) values(4 , 1 , 50); insert into score(s_id,c_id,score) values(4 , 2 , 30); insert into score(s_id,c_id,score) values(4 , 3 , 20); insert into score(s_id,c_id,score) values(5 , 1 , 76); insert into score(s_id,c_id,score) values(5 , 2 , 87); insert into score(s_id,c_id,score) values(6 , 1 , 31); insert into score(s_id,c_id,score) values(6 , 3 , 34); insert into score(s_id,c_id,score) values(7 , 2 , 89); insert into score(s_id,c_id,score) values(7 , 3 , 98); #需求1:查询课程id为1 比 课程id为2 成绩高的学生的信息及课程分数 SELECT stu.*,sco1.score AS "语文",sco2.score AS "数学" FROM student stu LEFT JOIN score sco1 ON stu.id=sco1.s_id AND sco1.c_id=1 LEFT JOIN score sco2 ON stu.id=sco2.s_id AND sco2.c_id=2 WHERE sco1.score>sco2.score; #需求2:查询课程id为1 比 课程id为2 成绩低的学生的信息及课程分数 SELECT stu.*,sco1.score AS "语文",sco2.score AS "数学" FROM student stu LEFT JOIN score sco1 ON stu.id=sco1.s_id AND sco1.c_id=1 LEFT JOIN score sco2 ON stu.id=sco2.s_id AND sco2.c_id=2 WHERE sco1.score<sco2.score; #需求3:查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩 SELECT sco.s_id,stu.name,sco.score,ROUND(AVG(sco.score),2)AS "avgScore" FROM student stu LEFT JOIN score sco ON stu.id=sco.s_id GROUP BY sco.s_id HAVING AVG(sco.score)>=60; #需求4:查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩(包括有成绩的和无成绩的) SELECT stu.id,stu.name,ROUND(AVG(sco.score),2)AS"avgscore" FROM student stu LEFT JOIN score sco ON stu.id=sco.s_id GROUP BY sco.s_id HAVING AVG(sco.score)<60; #需求5:查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩 SELECT stu.id,stu.name,COUNT(cou.id)AS "选课总数",SUM(sco.score)AS"总成绩" FROM score sco LEFT JOIN course cou ON sco.c_id=cou.id LEFT JOIN student stu ON sco.s_id=stu.id GROUP BY sco.s_id; SELECT stu.id,stu.name,count(sco.c_id), (CASE WHEN sum(sco.score) IS NULL THEN 0 ELSE sum(sco.score) END) FROM student stu LEFT JOIN score sco ON stu.id=sco.s_id GROUP BY stu.id; #需求6:查询"波"姓老师的数量 SELECT COUNT(id) FROM teacher WHERE name LIKE"波%"; #需求7:查询学过"何"老师授课的同学的信息 SELECT stu.* FROM score sco LEFT JOIN student stu ON stu.id=sco.s_id LEFT JOIN course cou ON cou.id=sco.c_id LEFT JOIN teacher tea ON cou.t_id=tea.id WHERE tea.name ="何"; #需求8:何老师授课相关信息 SELECT * FROM score sco LEFT JOIN course cou ON cou.id=sco.c_id LEFT JOIN teacher tea ON cou.t_id=tea.id LEFT JOIN student stu ON stu.id=sco.s_id WHERE tea.name="何"; -- # 何老师教的课 -- SELECT cou.* -- FROM course cou -- LEFT JOIN teacher tea ON tea.id=cou.t_id -- WHERE tea.name="何"; -- -- SELECT * -- FROM course -- WHERE t_id = ( -- SELECT id -- FROM teacher -- WHERE name='何'); -- -- #有何老师课成绩的学生id -- SELECT s_id -- FROM score -- WHERE c_id = -- (SELECT id -- FROM course -- WHERE t_id = ( -- SELECT id -- FROM teacher -- WHERE name='何')); -- -- SELECT sco.s_id -- FROM score sco -- WHERE sco.c_id IN -- (SELECT cou.id -- FROM course cou -- LEFT JOIN teacher tea ON tea.id=cou.t_id -- WHERE tea.name="何"); -- -- -- # 没学过何老师授课的同学信息 -- SELECT * FROM student WHERE id NOT IN -- (SELECT s_id FROM score WHERE score.c_id in -- (SELECT cou.id FROM course cou -- LEFT JOIN teacher tea ON cou.t_id=tea.id -- WHERE tea.name='何')); #需求9:查询学过编号为1并且也学过编号为2的课程的同学的信息 SELECT stu.* FROM student stu INNER JOIN score sco1 ON stu.id=sco1.s_id AND sco1.c_id=1 INNER JOIN score sco2 ON stu.id=sco2.s_id AND sco2.c_id=2; -- SELECT stu.* FROM student stu INNER JOIN score sco ON stu.id=sco.s_id AND sco.c_id=1 -- WHERE stu.id IN ( -- SELECT stu.id FROM student stu -- INNER JOIN score sco ON stu.id=sco.s_id AND sco.c_id=2 -- ) SELECT stu.* FROM student stu INNER JOIN score sco ON sco.s_id=stu.id GROUP BY stu.id HAVING SUM(IF(sco.c_id=1 OR sco.c_id=2 ,1,0))>1 #需求10:查询学过编号为1但是没有学过编号为2的课程的同学的信息 SELECT stu.* FROM student stu LEFT JOIN score sco1 ON stu.id=sco1.s_id AND sco1.c_id=1 LEFT JOIN score sco2 ON stu.id=sco2.s_id AND sco2.c_id=2 WHERE sco1.s_id IS NOT NULL AND sco2.s_id IS NULL; -- SELECT stu.* FROM student stu INNER JOIN score sco ON stu.id=sco.s_id AND sco.c_id=1 -- WHERE stu.id NOT IN ( -- SELECT stu.id FROM student stu -- INNER JOIN score sco ON stu.id=sco.s_id AND sco.c_id=2 -- )