SQL-DDL、DML、DCL

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
-- 	)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值