DAY07
一、条件查询
USE offcnoa;
-- 关系表达式查询
-- 查询薪资大于2000的员工信息
SELECT * FROM emp WHERE sal > 2000;
-- 查询员工的job 不是'manager'
SELECT * FROM emp WHERE job != 'manager';
-- 逻辑表达式
-- 查询员工的薪资大于2000 并且小于3000的员工名,薪资
SELECT ename,sal FROM emp WHERE sal > 2000 AND sal < 3000;
-- 查询员工的薪资不在 2000 到 3000之间的 员工名和薪资
SELECT ename,sal FROM emp WHERE sal <= 2000 OR sal >= 3000;
SELECT ename,sal FROM emp WHERE NOT(sal > 2000 AND sal < 3000);
-- 模糊查询 like %匹配任意字符 _匹配单个字符
-- 查询名中第一个字符为s的员工信息
SELECT * FROM emp WHERE ename LIKE 's%';
-- 查询名中第二个字符为m ,第五个字符为h的员工信息
SELECT * FROM emp WHERE ename LIKE '_m__h%';
-- 查询员工名中第二个字符为_的员工信息 \_将_转成普通字符
SELECT * FROM emp WHERE ename LIKE '_\_%';
/*
between...and
特点:
1. between 后小值 and 后大值
2. 既包含between后的值 又包含and后的值
*/
-- 查询员工年薪(不包括补助)在2W到4W之间的 员工的年薪和名字
SELECT sal*12 AS 年薪,ename FROM emp WHERE sal*12 BETWEEN 20000 AND 40000;
/*
ifnull(参数1,参数2)
判断参数1 字段名称
参数1为null 取参数2的值,参数1不为null 取参数1 的值
*/
-- 查询员工年薪(包括补助)在2W到4W之间的 员工的年薪和名字
SELECT sal,comm,ename,(sal + IFNULL(comm,0))*12 FROM
emp WHERE (sal + IFNULL(comm,0))*12 BETWEEN 20000 AND 40000;
-- in(元素的罗列) 在 ...之内 not in
-- 查询部门编号为20或者30的员工信息
SELECT * FROM emp WHERE deptno = 20 OR deptno = 30;
SELECT * FROM emp WHERE deptno IN(20,30);
-- 查询员工的补助为null 的员工信息
SELECT * FROM emp WHERE comm IS NULL;
-- 查询员工的补助不为null 的员工信息
SELECT * FROM emp WHERE comm IS NOT NULL;
-- 查询部门编号为不为20也不为30的员工信息
SELECT * FROM emp WHERE deptno != 20 AND deptno != 30;
SELECT * FROM emp WHERE deptno NOT IN(20,30);
-- 查询薪资不在2000到3000之间的员工信息
SELECT * FROM emp WHERE NOT (sal >= 2000 AND sal <= 3000);
/*总结:
条件查询关键字 where
逻辑运算符 and 并且 or 或者 not() 取反
运算符 > < >= <= != <>
模糊查询 like '' %匹配任意字符 _匹配单个字符 \_
在...之内 in() not in()
ifnull(参数1,参数2) 参数1字段名 字段名为null取参数2的值 不为null 取自己
空查询 is null is not null*/
二、数学函数
-- 向上取整 ceil()
SELECT CEIL(12.34);
-- 向下取整 floor
SELECT FLOOR(12.34);
-- 随机数 rand()[0,1)
SELECT RAND();
-- 生成100 -200 之间随机整数
SELECT FLOOR(RAND() * 101 + 100);
-- 绝对值 abs
SELECT ABS(-12.3);
-- 取余数 mod()
SELECT MOD(10,3); -- 余数为1 除数为0返回结果为null
-- 四舍五入 round
SELECT ROUND(12.49);-- 12
三、字符函数
USE offcnoa;
-- length() 长度
SELECT LENGTH('adasdfsdaf');
SELECT LENGTH(ename) FROM emp;
-- 转小写lower()
SELECT LOWER('AbCd');
SELECT LOWER(ename) FROM emp;
-- 转大写 upper()
SELECT UPPER('aBcD');
-- 截取字符 substr(字段,index,count) 从第index个字符开始 count 截取的长度
SELECT SUBSTR('abcdefg',2,3);
SELECT SUBSTRING(ename,1,2) FROM emp;
-- 去掉左右空格trim()
SELECT TRIM(' abcd ');
SELECT ' abcd ';
SELECT LENGTH(' abcd ');
SELECT LENGTH(TRIM(' abcd '));
-- 拼接字符串concat(参数1,参数2) 参数1参数2
SELECT CONCAT('ab','cd'); -- abcd
SELECT CONCAT(ename,'---',sal) FROM emp;
四、排序查询
-- 查询员工的名字和薪资 并且按照薪资降序 order by 字段 asc(默认)| desc降序
SELECT ename,sal FROM emp ORDER BY sal DESC;
-- 查询有补助的员工的名字和薪资 并且按照薪资升序
SELECT ename,sal FROM emp WHERE comm IS NOT NULL ORDER BY sal;
-- 查询员工的信息,并且按照薪资升序,相同薪资再按照名字降序
SELECT * FROM emp ORDER BY sal,ename DESC;
-- 查询名字中包含e字符的员工名字,薪资,按照年薪降序
SELECT ename,sal,(sal+IFNULL(comm,0))*12 FROM emp WHERE ename LIKE '%e%' ORDER BY (sal+IFNULL(comm,0))*12 DESC;
-- 查询名字中包含e字符的员工名字,薪资,按照年薪降序
SELECT ename,sal,(sal+IFNULL(comm,0))*12 AS 年薪 FROM emp WHERE ename LIKE '%e%' ORDER BY 年薪 DESC;
五、日期函数
-- 查询当前系统时间
SELECT NOW();
-- 格式化日期 date_format()
SELECT DATE_FORMAT(NOW(),'%Y年%m月%d日 %H时%i分%S秒');
-- 字符串解析成日期
SELECT STR_TO_DATE('2021年-29日-06月','%Y年-%d日-%m月');
-- 获取年月日 year() month() day()
SELECT YEAR(NOW());
SELECT MONTH(hiredate),DAY(hiredate) FROM emp;
-- 获取当前日期
SELECT CURDATE();
-- 获取当前时间
SELECT CURTIME();
六、分支函数结构
-- 如果薪资>2000显示正常 薪资 如果薪资小于等于2000显示偏低
-- IF(sal > 2000,'正常','偏低') sal > 2000 取正常 否则取偏低
SELECT ename,sal,IF(sal>2000,'正常','偏低') FROM emp;
-- 查询员工的名字和旧薪资、新薪资
#如果部门id = 10 薪资显示3倍
#如果部门id = 20 薪资显示2倍
#否则 薪资为4倍
SELECT ename AS 姓名,sal AS 旧薪资,
CASE
WHEN deptno = 10 THEN sal*3
WHEN deptno = 20 THEN sal*2
ELSE sal*4
END AS 新薪资
FROM emp;
七、聚合函数
/*
聚合函数一般配合着分组使用group by
max() 最大值
min() 最小值
sum() 总和
avg() 平均值
count() 个数
*/
-- 求最高薪资
SELECT MAX(sal) FROM emp;
-- 求最低薪资
SELECT MIN(sal) FROM emp;
-- 求平均值
SELECT AVG(sal) FROM emp;
SELECT AVG(comm) FROM emp;
-- 求总和
SELECT SUM(comm) FROM emp;
-- 求个数
SELECT COUNT(ename) FROM emp;
SELECT COUNT(comm) FROM emp; -- 3 忽略null
-- 查询表中有多少条数据
SELECT COUNT(ename) FROM emp;
SELECT COUNT(*) FROM emp;-- 查询表中多少条数据,使用主键字段或者*
八、分组查询
/*
分组 group by having
结论:有分组前面查询的字段只能 分组字段和聚合函数
from > where > group by > having > order by
where和having的区别
1、where可以单独使用 having不能单独使用,必须配合group by使用
2、where是对原始表中的数据进行筛选,having是对分组后的数据进行筛选
3、where后面不可以跟聚合函数,having可以跟聚合函数
*/
# 案例1: 查询每个部门的平均薪资
SELECT deptno,AVG(sal) FROM emp GROUP BY deptno;
# 案例2:查询每个job的最高薪资
SELECT job,MAX(sal) FROM emp GROUP BY job;
# 2. 添加分组前筛选 where > group by
# 案例3:查询有补助的 每个部门的最低薪资
SELECT * FROM emp WHERE comm IS NOT NULL;
SELECT deptno,MIN(sal) FROM emp WHERE comm IS NOT NULL GROUP BY deptno;
# 3. 添加分组后筛选 having 对分组后的数据进行筛选
# 案例4:查询哪个部门的平均薪资大于2500
-- 先求出每个部门的平均薪资 where后面不能跟聚合函数
SELECT AVG(sal),deptno FROM emp GROUP BY deptno HAVING AVG(sal) > 2500;
SELECT AVG(sal) a,deptno FROM emp GROUP BY deptno HAVING a > 2500;
# 4. 添加排序 having > order by
# 案例5:查询哪个部门的平均薪资小于2500,并且按照平均薪资升序
-- 查询每个部门的平均薪资
SELECT AVG(sal),deptno FROM emp GROUP BY deptno;
-- 小于2500
SELECT AVG(sal),deptno FROM emp GROUP BY deptno HAVING AVG(sal) < 2500;
-- 添加排序
SELECT AVG(sal),deptno FROM emp GROUP BY deptno HAVING AVG(sal) < 2500 ORDER BY AVG(sal) ASC;
九、分页查询
/*
分页关键字 limit
limit 在order by 后面执行
limit count; 查询前count条数据
limit index,count; 从索引index开始查询前count条数据 index从0开始的
*/
-- 查询前4条数据
SELECT * FROM emp LIMIT 4;
-- 查询第2-3条数据
SELECT * FROM emp LIMIT 1,2;
-- 分页 每页显示3条数
SELECT * FROM emp LIMIT 0,3;
-- 第二页
SELECT * FROM emp LIMIT 3,3;
-- 第三页
SELECT * FROM emp LIMIT 6,3;
-- 第n页
SELECT * FROM emp LIMIT(n-1)*3,3;
-- -- 求出最低薪资 显示姓名,部门编号
SELECT ename,deptno,sal FROM emp ORDER BY sal LIMIT 1;
十、一对多查询 外键设置
CREATE DATABASE day07 CHARSET utf8;
USE day07;
CREATE TABLE `user`(
uid INT PRIMARY KEY AUTO_INCREMENT,
uname VARCHAR(20)
);
CREATE TABLE `order`(
oid INT PRIMARY KEY,
oname VARCHAR(20)
);
INSERT INTO `user` VALUES(1,'张三'),(2,'李四');
INSERT INTO `order` VALUES(1001,'手机'),(1002,'平板');
-- 笛卡尔积 交叉连接
-- 张三--手机 李四 平板
SELECT * FROM `user`,`order`;
INSERT INTO `user` VALUES(3,'王五');
INSERT INTO `order` VALUES(1003,'笔记本'),(1004,'零食');
ALTER TABLE `order` ADD uid INT;
-- 代码设置外键
-- ADD 添加 CONSTRAINT 约束 fk_uo 外键名称自己取的
-- FOREIGN KEY 外键 REFERENCES 参考
ALTER TABLE `order` ADD CONSTRAINT fk_uo FOREIGN KEY(uid) REFERENCES `user`(uid);
-- 查询张三的订单
-- 通过张三查询到主键
SELECT uid FROM `user` WHERE uname = '张三';
SELECT oname FROM `order` WHERE uid = 1;
十一、连接查询
USE day07;
-- 隐式内连接 where
-- 先将两张表关联起来 连接条件 就是外键
SELECT * FROM `user`,`order` WHERE `user`.uid = `order`.oid;
SELECT * FROM `user` AS u,`order` AS o WHERE u.uid = o.uid ;
-- 查询张三的订单
SELECT * FROM `user` AS u,`order` AS o
WHERE u.uid = o.oid AND u.uname = '张三';
SELECT o.oid,o.oname,o.uid FROM `user` AS u,`order` AS o
WHERE u.uid = o.uid AND u.uname = '张三';
SELECT o.* FROM `user` AS u,`order` AS o
WHERE u.uid = o.uid AND u.uname = '张三';
-- 笔记本是哪个用户的订单
SELECT * FROM `user` u,`order` o WHERE u.uid = o.oid AND
o.oname = '笔记本';
-- 显示内连接 inner join on
-- 先把两张表关联起来
SELECT * FROM `user` u INNER JOIN `order` o ON u.uid = o.oid;
-- 查询张三的所有订单
SELECT * FROM `user` u INNER JOIN `order` o
ON u.uid = o.uid AND u.uname = '张三';
-- 左外连接 left join on
-- 以左表为主表,以右表为从表,会将主表中的所有数据都查询出来,
-- 从表不满足条件的使用null进行填充 以左为尊
-- 查询张三的所有订单
SELECT * FROM `order` o LEFT JOIN `user` AS u
ON u.uid = o.uid AND u.uname = '张三';
-- 右外连接 right join on
/*
-- 以右表为主表,以左表为从表,会将主表中的所有数据都查询出来,
-- 从表不满足条件的使用null进行填充 以右为尊
*/
-- 查询张三的所有订单
SELECT * FROM `order` o RIGHT JOIN `user` AS u
ON u.uid = o.uid AND u.uname = '张三';
作业
USE offcnoa;
-- 1、查询员工的姓名
SELECT ename FROM emp;
-- 2、查询员工的薪水以及姓名
SELECT ename,sal FROM emp;
-- 3、查询员工表所有的数据
SELECT * FROM emp;
-- 4、查询每一个员工的年薪(包含补助)
SELECT ename AS 姓名,(sal + IFNULL(comm,0))*12 AS 年薪 FROM emp;
-- 5、查询薪水为5000的员工
SELECT * FROM emp WHERE sal = 5000;
-- 6、查询职位为 MANAGER 的员工的信息
SELECT * FROM emp WHERE job = 'manager';
-- 7、查询薪水不等于5000的员工的信息
SELECT * FROM emp WHERE sal != 5000;
-- 8、查询职位不是MANAGER 的员工的信息
SELECT * FROM emp WHERE job != 'manager';
-- 9、薪水大于1600的员工信息
SELECT * FROM emp WHERE sal > 1600;
-- 10、薪水在1600和3000之间的员工信息
SELECT * FROM emp WHERE sal > 1600 AND sal < 3000;
-- 11、查询部门编号为20或者30的部门信息
SELECT * FROM dept WHERE deptno = 20 OR deptno = 30;
-- 12、查询部门编号为20或者30的信息
SELECT * FROM emp WHERE deptno IN(20,30);
-- 13、查询部门编号不为20也不为30的信息
SELECT * FROM emp WHERE deptno NOT IN(20,30);
-- 14、要求第一个字母带有s的员工的信息
SELECT * FROM emp WHERE ename LIKE 's%';
-- 15、要求第二个字母带有m的员工的信息
SELECT * FROM emp WHERE ename LIKE '_m%';
-- 16、根据员工的薪水排序(升序)
SELECT ename,sal FROM emp ORDER BY sal ASC;
-- 17、根据员工的薪水排序(降序)
SELECT ename,sal FROM emp ORDER BY sal DESC;
-- 18、员工入职日期降序查询
SELECT ename,hiredate FROM emp ORDER BY hiredate DESC;
-- 19、查询职位为MANAGER 的员工信息,并且按照薪资从高到低排序
SELECT * FROM emp WHERE job = 'manager'ORDER BY sal DESC;
-- 20、查询emp前五条数据
SELECT * FROM emp LIMIT 5;
-- 21、员工每页5条数据,查询前三页
SELECT * FROM emp LIMIT 0,5;
SELECT * FROM emp LIMIT 5,5;
SELECT * FROM emp LIMIT 10,5;
ALTER TABLE emp ADD CONSTRAINT fk_ed FOREIGN KEY(deptno) REFERENCES dept(deptno);
-- 22、查询JAMES的部门地址
SELECT dept.loc FROM dept,emp WHERE dept.deptno = emp.deptno AND emp.ename = 'james';
-- 23、查询RESEARCH部门所有员工信息
SELECT emp.* FROM dept,emp WHERE dept.DEPTNO = emp.DEPTNO AND
dept.DNAME = 'research';