[MySQL] 零基础学MySQL 05

本博客是【韩顺平讲MySQL】零基础一周学会MySQL -sql mysql教程 mysql视频 mysql入门视频的学习笔记

统计函数(合计函数)
count

count返回行的总数

Select count(*) | count(列名) from tablename [where where_definition]

练习

  • 统计一个班级共有多少学生
  • 统计数学成绩大于90的学生有多少个
  • 统计总分大于250的人数有多少
  • count(*)和count(列)的区别
SELECT COUNT(*) FROM student;
SELECT COUNT(*) FROM student WHERE math>90;
SELECT COUNT(*) FROM student WHERE (chinese+english+math) >250; 
#count(*)返回满足条件的记录的总行数
#count(列) 统计满足条件的某列有多少个,但是会排除为空的情况
CREATE TABLE t16(
	`name` VARCHAR(20));
INSERT INTO t16 VALUES('tom');
INSERT INTO t16 VALUES('jack');
INSERT INTO t16 VALUES('marry');
INSERT INTO t16 VALUES(NULL);
SELECT * FROM t16;

SELECT COUNT(*) FROM t16;#返回4
SELECT COUNT(`name`) FROM t16;#返回3
sum

sum函数返回满足where条件的行的和,一般使用在数值列

SELECT sum(列名){,sum(列名)...} from tablename [where where_definition]

练习

  • 统计一个班级数学总成绩
  • 统计一个班级语文、英语、数学各科的总成绩
  • 统计一个班级语文、英语、数学的成绩总和
  • 统计一个班级语文成绩平均分

注意:
     sum仅对数值起作用,否则没有意义
     对多列求和,“,”号不能少

SELECT SUM(math) FROM student;
SELECT SUM(chinese),SUM(english),SUM(math) FROM student;
SELECT SUM(chinese+english+math) FROM student;
SELECT SUM(chinese)/COUNT(*) FROM student;
avg

AVG函数返回满足where条件的一列的平均值

select avg(列名) {,avg(列名)...} from tablename
		[where where_definition]

练习

  • 求一个班级数学平均分
  • 求一个班级总分平均分
SELECT AVG(math) FROM student;
SELECT AVG(chinese+english+math) FROM student;
max/min
select max(列名) from tablename
		[where where_definition]

练习:求班级最高分和最低分

分组统计 group by

使用group by子句对列进行分组

SELECT column1,column2,column3.. FROM table
		group by column

使用having子句对分组后的结果进行过滤

SELECT column1,column2,column3..
		FROM table
		group by column having...

提前准备好的测试数据

#部门表
CREATE TABLE dept(
    deptno MEDIUMINT NOT NULL DEFAULT 0,
    dname VARCHAR(20) NOT NULL DEFAULT "",
    loc VARCHAR(13) NOT NULL DEFAULT ""
);
INSERT INTO dept VALUES(10,'ACCOUNTING','NEW YORK'),
    (20,'RESEARCH','DALLAS'),
    (30,'SALES','CHICAGO'),
    (40,'OPERATIONS','BOSHTON');  
SELECT * FROM dept;
#员工表
CREATE TABLE emp(
	empno MEDIUMINT  UNSIGNED NOT NULL DEFAULT 0,/*编号*/
	ename VARCHAR(20) NOT NULL DEFAULT "",/*名字*/
	job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/
	mgr MEDIUMINT UNSIGNED,/*上级编号*/
	hiredate DATE NOT NULL, /*入职时间*/
	sal DECIMAL(7,2) NOT NULL,/*薪水*/
	comm DECIMAL(7,2),/*红利*/
	deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0/*部门编号*/
);
#添加测试数据
INSERT INTO emp VALUES(7369,'SMITH','CLERK',7902,'1990-12-17',800.00,NULL,20),
    (7499,'ALLEN','SALESMAN',7698,'1991-2-20',1600.00,300.00,30),
    (7521,'WARD','SALESMAN',7968,'1991-2-22',1250.00,500.00,30),
    (7566,'JONES','MANAGER',7839,'1991-4-2',2975.00,NULL,20),
    (7654,'MARTIN','SALESMAN',7968,'1991-9-28',1250.00,1400.00,30),
    (7698,'BLAKE','MANAGER',7839,'1991-5-1',2850.00,NULL,30),
    (7782,'CLARK','MANAGER',7839,'1991-6-9',2450.00,NULL,10),
    (7788,'SCOTT','ANALYST',7566,'1991-4-19',3000.00,NULL,20),
    (7839,'KING','PRESIDENT',NULL,'1991-11-17',5000.00,NULL,10),
    (7844,'TURNER','SALESMAN',7698,'1991-9-8',1500.00,NULL,30),
    (7900,'JAMES','CLERK',7698,'1991-12-3',950.00,NULL,30),
    (7902,'FORD','ANALYST',7566,'1991-12-3',3000.00,NULL,20),
    (7934,'MILLER','CLERK',7782,'1991-1-23',1300.00,NULL,10);
SELECT * FROM emp;
#工资级别表
CREATE TABLE salgrade(
    grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*工资级别*/
    losal DECIMAL(17,2) NOT NULL,/*该级别的最低工资*/
    hisal DECIMAL(17,2) NOT NULL/*该级别的最高工资*/
);
INSERT INTO salgrade VALUES(1,700,1200),
    (2,1201,1400),
    (3,1401,2000),
    (4,2001,3000),
    (5,3001,9999);
SELECT * FROM salgrade;

写sql语句的思路:化繁为简,逐个击破。

#演示group by+having
#显示每个部门的平均工资和最高工资
#分析 avg(sal) max(sal)
#按照部门来分组查询
SELECT AVG(sal),MAX(sal),deptno
	FROM emp GROUP BY deptno;
#显示每个部门的每种岗位的平均工资和最低工资
SELECT AVG(sal),MIN(sal),deptno FROM emp GROUP BY deptno/*这是每个部门的平均工资和最低工资*/
SELECT AVG(sal),MIN(sal),deptno,job FROM emp GROUP BY deptno,job;/*这是每个部门的每种岗位的平均工资和最低工资*/
#显示平均工资低于2000的部门号和它的平均工资
#分析 写sql语句的思路 化繁为简,逐个击破
SELECT AVG(sal),deptno FROM emp GROUP BY deptno;/*显示各个部门的平均工资和部门号*/
#在上面的结果基础上进行过滤(筛选),保留平均工资小于2000的 这时就需要用到having
SELECT AVG(sal),deptno FROM emp GROUP BY deptno HAVING AVG(sal)<2000;
#可以使用别名进行过滤
SELECT AVG(sal) AS avg_sal,deptno
	FROM emp GROUP BY deptno HAVING avg_sal<2000;

在这里插入图片描述

字符串函数

以下大部分图片来自【韩顺平讲MySQL】零基础一周学会MySQL -sql mysql教程 mysql视频 mysql入门

在这里插入图片描述

#演示字符串相关函数的使用 使用emp表来演示
SELECT CHARSET(ename) FROM emp;
#连接字串,将多个列拼接成一列
SELECT CONCAT(ename,' job is ',job) FROM emp;
#dual 亚元表,是系统表,可以作为一个测试表来使用
SELECT INSTR('helloworld','world') FROM DUAL;
#转成大写或小写
SELECT UCASE(ename) FROM emp;
SELECT LCASE(ename) FROM emp;
#LEFT(string2,length) 从string2中的左边起取length个字符
SELECT LEFT(ename,2) FROM emp;
SELECT RIGHT(ename,2) FROM emp;
#LENGTH(string) 长度
SELECT LENGTH(ename) FROM emp;
SELECT LENGTH('刘华强') FROM DUAL;/*9 说明是按字节返回的*/
SELECT LENGTH('lhq') FROM DUAL;/*3 说明是按字节返回的*/
#replace(str,search_str,replace_str) 在str中用replace_str替换search_str
SELECT * FROM emp;
#如果是 manager 就替换成经理
SELECT `ename`,REPLACE(job,'MANAGER','经理') FROM emp;
#strcmp 逐字符比较两个字符串的大小
SELECT STRCMP('lhq','lhq') FROM DUAL;/*0*/
SELECT STRCMP('lhq','jhq') FROM DUAL;/*1*/
SELECT STRCMP('hhh','jjj') FROM DUAL;/*-1*/
#substring(str,position [,length]) 从str的position开始[从1开始计算],取length个字符
SELECT SUBSTRING(ename,2,4) FROM emp;/*从ename的第2个位置开始取出4个字符*/
#ltrim(string2) rtrim(string2) trim(string2) 去除前端空格或者后端空格或者左右都去
SELECT LTRIM('   hello   ') FROM DUAL;
SELECT RTRIM('   hello   ') FROM DUAL;
SELECT TRIM('   hello   ') FROM DUAL;

练习:以首字母小写的方式显示所有员工的姓名 emp表

#先取出名字的第一个字符,然后转成小写,再和后面的内容进行拼接输出即可
SELECT LCASE(LEFT(ename,1)) FROM emp;
SELECT CONCAT(LCASE(LEFT(ename,1)),SUBSTRING(ename,2)) AS new_name FROM emp;
数学函数

在这里插入图片描述

#演示数学相关函数
#绝对值
SELECT ABS(-10) FROM DUAL;/*10*/
#十进制转成二进制
SELECT BIN(10) FROM DUAL;/*1010*/
#ceiling(num2) 向上取整 得到比num2大的最小整数
SELECT CEILING(1.1) FROM DUAL;/*2*/
SELECT CEILING(-1.1) FROM DUAL;/*-1*/
#conv(num2,from_base,to_base) 进制转换
SELECT CONV(8,10,2) FROM DUAL;/*8是十进制的8 转成二进制输出 返回1000*/ 
SELECT CONV('A',16,10) FROM DUAL;/*10*/
#floor(num2) 向下取整 得到比num2小的最大整数
SELECT FLOOR(1.1) FROM DUAL;/*1*/
SELECT FLOOR(-1.1) FROM DUAL;/*-2*/
#format保留小数位数
SELECT FORMAT(78.12345,2) FROM DUAL;/*会四舍五入 78.12*/
SELECT FORMAT(78.12533,2) FROM DUAL;/*78.13*/
SELECT FORMAT(AVG(sal),2),MAX(sal),deptno 
	FROM emp GROUP BY deptno;
#least(num1,num2,...) 求最小值
SELECT LEAST(0,1,-10,4) FROM DUAL;/*-10*/
#mod 求余
SELECT MOD(10,3) FROM DUAL;/*1*/
#rand([seed] rand [seed]) 其范围为0<=v <=1.0
SELECT RAND() FROM DUAL;
#如果想让随机数不变化,可以给一个随机种子
SELECT RAND(3) FROM DUAL;
时间日期相关函数

在这里插入图片描述

#日期时间相关函数
SELECT CURRENT_DATE() FROM DUAL;
SELECT CURRENT_TIME() FROM DUAL;
SELECT CURRENT_TIMESTAMP FROM DUAL;
#创建测试表
CREATE TABLE mes(id INT,content VARCHAR(30),send_time DATETIME);
SELECT * FROM mes;
#添加一条记录
INSERT INTO mes VALUES(1,'北京新闻',CURRENT_TIMESTAMP);
SELECT * FROM mes;

在这里插入图片描述

SELECT NOW() FROM DUAL;
INSERT INTO mes VALUES(2,'上海新闻',NOW());
INSERT INTO mes VALUES(3,'广州新闻','2021-10-28 16:00:00');
SELECT * FROM mes;

#应用实例
#显示所有新闻信息,发布日期只显示日期,不用显示时间
SELECT id,content,DATE(send_time) FROM mes;
#请查询在10分钟内发布的新闻
SELECT * 
	FROM mes
	WHERE DATE_ADD(send_time,INTERVAL 10 MINUTE)>=NOW();

SELECT *
	FROM mes
	WHERE DATE_SUB(NOW(),INTERVAL 10 MINUTE)<=send_time;
#请在mysql的sql语句中求出2011-11-11和1990-1-1相差几天
SELECT DATEDIFF('2011-11-11','1990-01-01') FROM DUAL;
#请用mysql的sql语句求出你活了多少天
SELECT DATEDIFF(DATE(NOW()),'xxxx-xx-xx') FROM DUAL;
#如果你能活80岁,求出你还能活多少天
#先求出活到80岁是什么日期,再将这个日期和NOW()相减
SELECT DATE_ADD('xxxx-xx-xx',INTERVAL 80 YEAR) FROM DUAL;
SELECT DATEDIFF(DATE_ADD('xxxx-xx-xx',INTERVAL 80 YEAR),NOW()) FROM DUAL;

一些细节:

  1. DATE_ADD()中的interval后面可以是year hour minute second day等
  2. DATE_SUB()中的interval后面可以是year hour minute second day等
  3. DATEDIFF(date1,date2)得到的是天数,而且是date1-date2的天数,因此可以取负数
  4. 这四个函数的日期类型可以是date,datetime或者timestamp

在这里插入图片描述

SELECT YEAR(NOW()) FROM DUAL;
SELECT HOUR(NOW()) FROM DUAL;
SELECT YEAR('2013-10-10') FROM DUAL;

#unix_timestamp()返回1970-1-1到现在的秒数
SELECT UNIX_TIMESTAMP() FROM DUAL;
#from_unixtime() 可以把一个unix_timestamp秒数[时间戳]转成指定格式的日期
#%Y-%m-%d格式是规定好的 表示年月日
#意义:在开发中,可以存放一个整数,然后表示时间,通过from_unixtime()转换
SELECT FROM_UNIXTIME(1635411445,'%Y-%m-%d') FROM DUAL;
SELECT FROM_UNIXTIME(1635411445,'%Y-%m-%d %H:%i:%s') FROM DUAL;
加密和系统函数

存放用户密码时,一定要使用加密函数加密!
在这里插入图片描述

#查询用户 返回 用户@IP地址
SELECT USER() FROM DUAL;
#查询当前使用的数据库名称
SELECT DATABASE() FROM DUAL;
#MD5(str) 为字符串算出一个MD5 32的字符串,常用于(用户密码)加密
# 密码->加密->在数据库中存放的是加密后的密码
SELECT MD5('abc') FROM DUAL;
SELECT LENGTH(MD5('abc')) FROM DUAL;
#演示:用户表存放密码时,是MD5
CREATE TABLE users1
	(id INT,`name` VARCHAR(32) NOT NULL DEFAULT '',
	 pwd CHAR(32) NOT NULL DEFAULT '');
INSERT INTO users1 
	VALUES(1,'dog',MD5('abc'));
SELECT * FROM users1;
SELECT * FROM users1
	 WHERE `name`='dog' AND pwd='abc';#这样是什么都找不到的
SELECT * FROM users1
	 WHERE `name`='dog' AND pwd=MD5('abc');
#password(str) 加密函数 Mysql数据库的用户密码就是用这个函数加密的
SELECT PASSWORD('abc') FROM DUAL;	 
#mysql.user表示 数据库.表 不想切换数据库时就可以指定数据库和表
SELECT * FROM mysql.user
流程控制函数

在这里插入图片描述

#演示流程控制语句
#if(expr1,expr2,expr3) 如果expr1为true,则返回expr2,否则返回expr3
#有点像三目运算符
SELECT IF(TRUE,'北京','上海') FROM DUAL;
SELECT IF(FALSE,'北京','上海') FROM DUAL;	 
# ifnull(expr1,expr2) 如果expr1不为空,则返回expr1,否则返回expr2
SELECT IFNULL(NULL,'abcd') FROM DUAL;	 
SELECT IFNULL('cat','dog') FROM DUAL;
#select case when expr1 then expr2 
#	when expr3 then expr4 else expr5 end;[类似多重分支]
#如果expr1为真,则返回expr2;如果expr3为真,则返回expr4;如果还不为真,则返回expr5
#只要有一个为真,就返回并且结束了
SELECT CASE 
	WHEN TRUE THEN 'expr2' 
	WHEN FALSE THEN 'expr4'
	ELSE 'expr5' END;/*expr2*/
SELECT CASE 
	WHEN FALSE THEN 'expr2' 
	WHEN TRUE THEN 'expr4'
	ELSE 'expr5' END;/*expr4*/
SELECT CASE 
	WHEN TRUE THEN 'expr2' 
	WHEN TRUE THEN 'expr4'
	ELSE 'expr5' END;/*expr2*/
SELECT CASE 
	WHEN FALSE THEN 'expr2' 
	WHEN FALSE THEN 'expr4'
	ELSE 'expr5' END;/*expr5*/

两个需求:

  1. 查询emp表,如果comm是null,则显示0.0
  2. 如果emp表的job是CLERK则显示 职员,如果是MANAGER则显示 经理 如果是SALESMAN则显示 销售人员,其他正常显示
#判断是否为空要使用 is null 判断是否非空要使用 is not null
SELECT `ename`,IF(comm IS NULL,0.0,comm) FROM emp;
SELECT `ename`,IFNULL(comm,0.0) FROM emp;
SELECT ename,(SELECT CASE
	        WHEN job='CLERK' THEN '职员'
		WHEN job='MANAGER' THEN '经理'
		WHEN job='SALESMAN' THEN '销售'
		ELSE job END) AS 'job'
	FROM emp;

SELECT ename,IF(job='CLERK','职员',IF(job='MANAGER','经理',IF(job='SALESMAN','销售',job))) AS job FROM emp;
从效果上看,也可以完成需求2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值