四、MySQL从入门到精通—MySQL函数
SQL语句的执行顺序(重点)
- FROM <left_table>
- ON <join_condition> (表连接条件)
- <join_type> JOIN <right_table>
- WHERE <where_condition> (一级过滤,WHERE后面不能使用别名,不能过滤聚合函数)
- GROUP BY <group_by_list> (识别SELECT中的别名,这里只能识别简单的SELECT字段的别名,不包含窗口函数的别名,后面的语句中都可以使用)
- WITH {CUBE | ROLLUP} (对分组后的数据进行汇总,对分组的字段取别名)
- HAVING <having_condition> (二级过滤,过滤聚合函数的值,以及普通字段)
- SELECT
- DISTINCT
- <TOP_specification> <select_list> (窗口函数)
- ORDER BY <order_by_list> (对数据集进行排序,可以识别窗口函数的别名)
- LIMIT OFFSET NUMBER (分页功能)
WHERE和ON的区别
ON为表连接条件,WHERE进行字段的一级过滤,将过滤条件能够写到ON的尽量写到ON中,减少连接的数据集
WHERE和HAVING的区别
WHERE只是对字段进行简单过滤,HAVING除了能对字段简单过滤以外,还能够对聚合值进行过滤
常用函数
数据函数
SELECT ABS(-8); /*绝对值*/ SELECT CEILING(9.4); /*向上取整*/ SELECT FLOOR(9.4); /*向下取整*/ SELECT RAND(); /*随机数,返回一个0-1之间的随机数*/ SELECT SIGN(0); /*符号函数: 负数返回-1,正数返回1,0返回0*/
字符串函数
SELECT CHAR_LENGTH('坚持就能成功'); /*返回字符串包含的字符数*/ SELECT CONCAT('我','爱','程序'); /*合并字符串,参数可以有多个*/ SELECT INSERT('我爱编程helloworld',1,2,'超级热爱'); /*替换字符串,从某个位置开始替换某个长度*/ SELECT LOWER('KuangShen'); /*小写*/(与Python中相同) SELECT UPPER('KuangShen'); /*大写*/ SELECT LEFT('hello,world',5); /*从左边截取*/ SELECT RIGHT('hello,world',5); /*从右边截取*/ SELECT REPLACE('坚持就能成功','坚持','努力'); /*替换字符串*/ SELECT SUBSTR('坚持就能成功',4,6); /*截取字符串,开始和长度*/ SELECT REVERSE('坚持就能成功'); /*反转 #查询姓赵的同学,改成李 SELECT REPLACE(studentname,'赵','李') AS 新名字 FROM student WHERE studentname LIKE '赵%';
日期和时间函数
SELECT CURRENT_DATE(); /*获取当前日期*/ SELECT CURDATE(); /*获取当前日期*/ SELECT NOW(); /*获取当前日期和时间*/ SELECT LOCALTIME(); /*获取当地的日期和时间*/ SELECT SYSDATE(); /*获取当前系统的日期和时间*/ -- 获取年月日,时分秒 SELECT YEAR(NOW()); SELECT MONTH(NOW()); SELECT DAY(NOW()); SELECT HOUR(NOW()); SELECT MINUTE(NOW()); SELECT SECOND(NOW());
系统信息函数
SELECT VERSION(); /*MySQL使用的版本*/ SELECT USER(); /*用户*/
聚合函数
函数名称 | 描述 |
---|---|
COUNT() | 返回满足Select条件的记录总和数,如 select count(*) (一般情况不使用,效率低) |
SUM() | 返回数字字段或表达式列作统计,返回一列的总和。 |
AVG() | 通常为数值字段或表达列作统计,返回一列的平均值(Average) |
MAX() | 可以为数值字段,字符字段或表达式列作统计,返回最大的值。 |
MIN() | 可以为数值字段,字符字段或表达式列作统计,返回最小的值。 |
-- 聚合函数 /*COUNT:非空的*/ SELECT COUNT(studentname) FROM student; SELECT COUNT(*) FROM student; SELECT COUNT(1) FROM student; /*推荐*/ -- 从含义上讲,count(1) 与 count(*) 都表示对全部数据行的查询(执行效果上)。 --1. count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况。即不统计字段为null 的记录。 --2. count(*) 包括了所有的列,相当于行数,在统计结果的时候,包含字段为null 的记录; --3. count(1) 会统计表中的所有的记录数,包含字段为null 的记录。 /* 很多人认为count(1)执行的效率会比count(*)高,原因是count(*)会存在全表扫描,而count(1)可以针对一个字段进行查询。其实不然,count(1)和count(*)都会对全表进行扫描,统计所有记录的条数,包括那些为null的记录,因此,它们的效率可以说是相差无几。而count(字段)则与前两者不同,它会统计该字段不为null的记录条数。 下面它们之间的一些对比: 1)在表没有主键且有多个列时,count(1)比count(*)快 2)有主键时,主键作为计算条件,count(主键)效率最高; 3)若表格只有一个字段,则count(*)效率较高。 */ SELECT SUM(StudentResult) AS 总和 FROM result; SELECT AVG(StudentResult) AS 平均分 FROM result; SELECT MAX(StudentResult) AS 最高分 FROM result; SELECT MIN(StudentResult) AS 最低分 FROM result;
题目:
-- 查询不同课程的平均分,最高分,最低分 -- 前提:根据不同的课程进行分组 -- 关键字之间也存在优先级WHERE > GROUP BY > HAVING SELECT subjectname,AVG(studentresult) AS 平均分,MAX(StudentResult) AS 最高分,MIN(StudentResult) AS 最低分 FROM result AS r INNER JOIN `subject` AS s ON r.subjectno = s.subjectno GROUP BY r.subjectno HAVING 平均分>80; /* where写在group by前面. 要是放在分组后面的筛选 要使用HAVING.. 因为having是从前面筛选的字段再筛选,而where是从数据表中的>字段直接进行的筛选的 */
MD5 加密
MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。
CREATE TABLE `testmd5` ( `id` INT(4) NOT NULL, `name` VARCHAR(20) NOT NULL, `pwd` VARCHAR(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 -- 插入一些数据 INSERT INTO testmd5 VALUES(1,'jiujiu','123456'),(2,'qinjiang','456789') -- 对pwd这一列数据进行加密,语法是: update testmd5 set pwd = md5(pwd); -- 单独对某个用户(如jiujiu)的密码加密: INSERT INTO testmd5 VALUES(3,'jiujiu','123456') update testmd5 set pwd = md5(pwd) where name = 'jiujiu'; -- 对插入新的数据实现自动加密 INSERT INTO testmd5 VALUES(4,'Coffee',md5('123456')); -- 查询登录用户信息(md5对比使用,查看用户输入加密后的密码进行比对) SELECT * FROM testmd5 WHERE `name`='jiujiu' AND pwd=MD5('123456');
SELECT小结
-- ================ 内置函数 ================ -- 数值函数 ABS(x) -- 绝对值 abs(-10.9) = 10 FORMAT(x, d) -- 格式化千分位数值 format(1234567.456, 2) = 1,234,567.46 CEILING(x) -- 向上取整 ceil(10.1) = 11 FLOOR(x) -- 向下取整 floor (10.1) = 10 ROUND(x) -- 四舍五入去整 MOD(m, n) -- m%n m mod n 求余 10%3=1 PI() -- 获得圆周率 POW(m, n) -- m^n SQRT(x) -- 算术平方根 RANDrand() -- 随机数 TRUNCATE(x, d) -- 截取d位小数 -- 时间日期函数 NOW(), CURRENT_TIMESTAMP(); -- 当前日期时间 CURRENT_DATE(); -- 当前日期 CURRENT_TIME(); -- 当前时间 DATE('yyyy-mm-dd hh:ii:ss'); -- 获取日期部分 TIME('yyyy-mm-dd hh:ii:ss'); -- 获取时间部分 DATE_FORMAT('yyyy-mm-dd hh:ii:ss', '%d %y %a %d %m %b %j'); -- 格式化时间 UNIX_TIMESTAMP(); -- 获得unix时间戳 FROM_UNIXTIME(); -- 从时间戳获得时间 -- 字符串函数 LENGTH(string) -- string长度,字节 CHAR_LENGTH(string) -- string的字符个数 SUBSTRING(str, position [,length]) -- 从str的position开始,取length个字符 REPLACE(str ,search_str ,replace_str) -- 在str中用replace_str替换search_str INSTR(string ,substring) -- 返回substring首次在string中出现的位置 LOCATE(substring, string [,start_position]) -- 同instr,但可指定开始位置 CONCAT(string [,...]) -- 连接字串 CHARSET(str) -- 返回字串字符集 LCASE(string) -- 转换成小写 LEFT(string, length) -- 从string2中的左边起取length个字符 LOAD_FILE(file_name) -- 从文件读取内容 LPAD(string, length, pad) -- 重复用pad加在string开头,直到字串长度为length RPAD(string, length, pad) -- 在str后用pad补充,直到长度为length LTRIM(string) -- 去除前端空格 RTRIM(string) -- 去除后端空格 REPEAT(string, count) -- 重复count次 STRCMP(string1 ,string2) -- 逐字符比较两字串大小 -- 聚合函数 COUNT() SUM(); MAX(); MIN(); AVG(); GROUP_CONTAC() -- 其他常用函数 MD5(); DEFAULT();