# 单行注释1-- 单行注释2# 创建CREATETABLE class(
id intNOTNULLAUTO_INCREMENT,
class_name varchar(50)NOTNULL,
class_teacher varchar(55)DEFAULTNULLCOMMENT'老师',PRIMARYKEY(id));CREATETABLE`student`(`id`intNOTNULLAUTO_INCREMENTCOMMENT'主键',`stu_name`varchar(50)CHARACTERSET utf8 COLLATE utf8_general_ci DEFAULTNULLCOMMENT'姓名',`gender`tinyint(1)DEFAULTNULLCOMMENT'性别 1-男 2-女\r\n',`class_id`intDEFAULTNULLCOMMENT'班级编号',`grade`intDEFAULTNULL,PRIMARYKEY(`id`)USINGBTREE)ENGINE=InnoDBAUTO_INCREMENT=13DEFAULTCHARSET=utf8mb3 COMMENT='学生基本信息表';# 查SELECT*FROM student;SELECT stu_name FROM student;# 增insertinto student(stu_name, gender)VALUES("小李",1);insertinto student(stu_name, gender)VALUES("小王",2);insertinto student(stu_name, gender)VALUES("小黄",2);insertinto class(class_name)VALUES("java");insertinto class set class_name ="C++", class_teacher ="罗翔";# 改UPDATE student set gender =1where grade =90;# 删DELETEFROM student;DELETEFROM student WHERE stu_name ='小王';DELETEFROM class;# 批量插入INSERTinto student(stu_name, gender)SELECT stu_name, gender FROM student WHERE gender =1;# 聚合函数-- 求总个数SELECTCOUNT(*)FROM student;SELECT*FROM student;-- 求平均值、最值、和SELECTAVG(grade)as avg_grade FROM student;SELECTMAX(grade)as max_grade FROM student;SELECTMIN(grade)as min_grade FROM student;SELECTsum(grade)as sum_grade FROM student;# 保留小数后几位,四舍五入SELECTROUND(3.1415926,4)# 查看数据库版本SELECT VERSION()# 当前数据库所在服务器的时间SELECTNOW()# 日期格式化SELECT"2021/2/12 13:45:32"SELECT DATE_FORMAT("2021/2/12 13:45:32","%Y-%m-%d %H:%i:%s")# 日期增加SELECT DATE_ADD(NOW(),INTERVAL1day);# 加一天SELECT DATE_ADD(NOW(),INTERVAL-1day);# 减一天SELECT DATE_ADD(NOW(),INTERVAL1HOUR);# 加一小时# 拼接字符SELECT CONCAT(stu_name, gender)as tar FROM student;# 关键字去重 distinctSELECT*FROM student;SELECTDISTINCT stu_name FROM student;# 在distinct后边有多个字段时, 会对字段的组合去重SELECTDISTINCT stu_name, id FROM student
关联、分组、排序、分页
# 1.多表联查# 查询所有学生信息及其所在班级名称SELECT
a.id,
a.stu_name,
a.gender,
b.cla_id,
b.cla_name
FROM
stu_info AS a,
cla_info AS b
WHERE
a.cla_id = b.cla_id;# 2.关联查询# 左连接 LEFT JOINSELECT*FROM
stu_info AS a
LEFTJOIN cla_info AS b ON a.cla_id = b.cla_id;# 右连接 RIGHT JOINSELECT*FROM
stu_info AS a
RIGHTJOIN cla_info AS b ON a.cla_id = b.cla_id;# 内连接 INNER JOIN (效果等于多表联查)SELECT*FROM
stu_info AS a
INNERJOIN cla_info AS b ON a.cla_id = b.cla_id;# 主键与外键# 主键具有唯一性, 可以是一个字段,也可以是多个字段的组合# 外键可以有多个# 分页 limitSELECT*FROM stu_info LIMIT1,3;# 从第二条开始,共查三条SELECT*FROM stu_info LIMIT3;#从第一条开始查的简写# pageNo页码 pageCount页数(每页查询的行数)# 第一页 pageNo = 1, LIMIT (pageNo-1)*3, 3SELECT*FROM stu_info LIMIT0,3;# 第二页 pageNo = 2, LIMIT (pageNo-1)*3, 3SELECT*FROM stu_info LIMIT3,3;# 第三页 pageNo = 3, LIMIT (pageNo-1)*3, 3SELECT*FROM stu_info LIMIT6,3;# 排序# 查询所有学生信息,要求按照成绩由高到低排序SELECT*FROM stu_info ORDERBY grade DESC;# 查询所有学生信息,要求按照成绩由低到高排序SELECT*FROM stu_info ORDERBY grade ASC;# 分组group by# 1.分组往往结合聚合函数使用# 2.对哪个字段进行分组, 查询出来的结果集,只展示当前分组的第一行# 统计每个班的学生人数 SELECT cla_id,COUNT(*)FROM stu_info GROUPBY cla_id;# 每个班的第一个学生SELECT*FROM stu_info GROUPBY cla_id;# HAVING对GROUP BY分组之后的数据集进行筛选# 学生所在的班级有哪些SELECT cla_id FROM stu_info GROUPBY cla_id HAVINGNOT ISNULL(cla_id);# 统计每个班的女生人数SELECT cla_id,COUNT(*)FROM(SELECT*FROM stu_info WHERE gender=0)AS t
GROUPBY cla_id;# 总结:WHERE/GROUP BY > ORDER BY > LIMIT# 执行顺序:from---where--group by---having---select---order by---limit# WHERE 必须放在 ORDER BY 前面SELECT*FROM stu_info WHERE gender=0ORDERBY grade DESC# WHERE 必须放在 LIMIT 前面 SELECT*FROM stu_info WHERE gender=0LIMIT2;# GROUP BY必须放在 ORDER BY前面# GROUP BY必须放在 LIMIT前面SELECT gender,COUNT(*)as x FROM stu_info
GROUPBY gender
ORDERBY x DESC;# ORDER BY 必须放在 LIMIT 前面SELECT*FROM stu_info ORDERBY grade LIMIT2;# 子查询# COLUMN IN (数据集) 判断字段的值是否在数据集中SELECT*FROM stu_info WHERE cla_id
IN(SELECT cla_id FROM cla_info)
# IF语句-- IF[判断条件] THEN [结果或结果集]-- ELSEIF [判断条件] THEN [结果或结果集]-- ELSE [结果或结果集]-- END IF;# 函数, 类似三元运算符# IF([condition],[value if true],[value if false])SELECT*,IF(gender=1,'男','女')as'性别'FROM stu_info WHERE id=3;# CASE语句(类似switch)-- CASE [字段]-- WHEN [判断值] THEN [结果或结果集]-- WHEN [判断值] THEN [结果或结果集]-- ELSE [结果或结果集]-- END;SELECT*,CASE gender
WHEN1THEN'男'WHEN0THEN'女'ELSE'嘿嘿'ENDAS'性别'FROM stu_info;# WHILE语句-- WHILE [] DO-- 执行sql-- END WHILE;
函数
函数有且只有一个返回值
函数返回值只能是一个值,不能是结果集
CREATEDEFINER=`root`@`localhost`FUNCTION`f_01`(`a`int,`b`int)RETURNSintDETERMINISTICBEGIN# 声明成员变量,关键字 DECLAREDECLARE res INTDEFAULT0;# 赋值 关键字 SETSET res = a + b;# 会话变量,规定变量名前加一个 @符号# 会话变量不需要声明,直接赋值用就行set@tar=TRUE;WHILE@tarDOSET res = res +1;IF res >10THENSET@tar=FALSE;ENDIF;ENDWHILE;RETURN res;END
存储过程
优点
可以封装,隐藏了复杂的业务逻辑。
可以预编译,提高数据库执行速度。存储过程只在创建时编译一次,之后每次执行存储过程都不需要再编译。
缺点
不能跨平台,不同的数据库系统有不同的存储过程定义方法。
难以调试。
CREATEDEFINER=`root`@`localhost`PROCEDURE`p_01`(IN`a`int,IN`b`int)BEGIN# 班级idDECLARE p_c_id int;# 最高成绩DECLARE p_max_grade int;# 查询宋丹丹老师的学生中,成绩最高的学生信息# 1 查询宋丹丹老师的任课班级SET p_c_id =(SELECT cla_id FROM cla_info WHERE cla_teacher ='宋丹丹');# 2 查找该班级最高的成绩SET p_max_grade =(SELECTMAX(grade)FROM stu_info WHERE cla_id = p_c_id);# 3 根据班级和成绩找到匹配的学生信息SELECT*FROM stu_info
where cla_id = p_c_id AND grade = p_max_grade;SET a= a+1;SELECT a;END
调用
CALL p_01(2,1);
游标
游标是一组有序的结果集。
mysql中,游标只能用于函数和过程。
mysql中,游标是单向、向前、逐个、只读的。
CREATEDEFINER=`root`@`localhost`PROCEDURE`p_02`(IN`id`int)BEGINDECLARE p_id INT;DECLARE p_name varchar(55);# 声明变量,控制遍历游标的循环终止DECLARE curStatus INTDEFAULT1;# 声明游标,该语句必须在所有sql执行语句(select/insert/update/delete)之前。DECLARE list CURSORFORSELECT id,stu_name FROM stu_info WHERE cla_id = id;# CONTINUE HANDLER 声明handler(处理器),handler会自动地向下读取游标的一行记录# 当handler读不到数据时(not found即异常号02000)表明已经读完了游标的数据,此时设置curStatus = 0DECLARECONTINUEHANDLERFOR SQLSTATE '02000'SET curStatus =0;# 开启游标OPEN list;# 向下读取一行数据,并将这行数据赋值给对应的变量FETCH list INTO p_id,p_name;#遍历游标WHILE curStatus =1DO# 执行sql语句INSERTINTO person_info SET name = p_name;FETCH list INTO p_id,p_name;ENDWHILE;# 关闭游标CLOSE list;SELECT*FROM person_info RIGHTJOIN stu_info ON person_info.`name`= stu_info.stu_name;END