多表查询
交叉查询
##########交叉查询(没用)或者笛卡尔积查询:多个表的数据的乘积
#问题:大量数据的冗余 , 在多表查询中 多表查询建立在笛卡尔积的基础上
##语法:select * from A , B, C,D.....
SELECT * FROM dept , emp;
SELECT COUNT(*) FROM dept , emp;
内连接
###########显示内连接
#语法: select * from A inner join B on 连接的条件
# inner join C on 连接的条件
# inner join D on 连接的条件 ...
SELECT * FROM dept INNER JOIN emp ON emp.dept_id=dept.id;
#细节 : 隐式内连接 对sql足够熟悉使用 显示内连接初学者使用
#细节 : 无论是哪一种内连接 最后的查询结果不会发生变化 , 只是字段顺序变化了
#细节 : 如果整个表中有且唯一的字段可以省略表名(建议不要省略)
#细节 : 如果单词过长 可以加入表别名 通过别名.字段 快速获得字段
左外连接和右外连接
##########外连接 : 结果跟表的放置顺序有关系
###########左外连接
#语法: select * from A left join B on 连接条件
# left join C on 连接条件
# left join D on 连接条件...
#以左表为主 将左表的数据全部查询出来 ,匹配右表的数据, 匹配成功正常显示数据
#匹配失败 , 右表数据以null方式展示
SELECT * FROM dept AS d
LEFT JOIN emp AS e ON d.id = e.dept_id;
SELECT * FROM emp AS e
LEFT JOIN dept AS d ON d.id = e.dept_id;
###########右外连接
#以右表为主 将右表的数据全部查询出来 ,匹配左表的数据, 匹配成功正常显示数据
#匹配失败 , 左表数据以null方式展示
#语法: select * from A right join B on 连接条件
# right join C on 连接条件
# right join D on 连接条件...
SELECT * FROM dept AS d
RIGHT JOIN emp AS e ON d.id = e.dept_id;
SELECT * FROM emp AS e
LEFT JOIN dept AS d ON d.id = e.dept_id;
/*
select * from A,B,C,D..... where 连接的条件 and where 连接的条件 基于笛卡尔积
非标准语法: 不建议inner省略 建议 outer省略
#语法: select * from A [inner] join B on 连接的条件
# [inner] join C on 连接的条件
# [inner] join D on 连接的条件 ...
#语法: select * from A left [outer] join B on 连接条件
# left [outer] join C on 连接条件
# left [outer] join D on 连接条件
#语法: select * from A right [outer] join B on 连接条件
# right [outer] join C on 连接条件
# right [outer] join D on 连接条件...
*/
子查询
即一条SELECT语句结果作为另一条SELECT语法一部分(作为查询条件或查询结果或表)
#一条SELECT语句结果作为另一条SELECT语法一部分(作为查询条件或查询结果或表)
#其实就是逻辑语句嵌套
#案例:查询emp表中工资最高的员工信息
#select * from emp where salary = 9000;
SELECT * FROM emp WHERE MAX(salary) = 9000;
#查询最高工资(一条SELECT语句结果)
SELECT MAX(salary) FROM emp;
#根据工资查询员工
SELECT * FROM emp WHERE salary = 最高工资(变量) ;
#演变 :子查询 加() 在()中加入另外一条sql即可 (作为另一条SELECT语法一部分)
SELECT * FROM emp WHERE salary = ( SELECT MAX(salary) FROM emp ) ;
#查询工资小于平均工资的员工有哪些
#平均工资
SELECT AVG(salary) FROM emp;
#查询工资小于平均工资的员工
SELECT * FROM emp WHERE salary < 平均工资
#演变
SELECT * FROM emp WHERE salary < ( SELECT AVG(salary) FROM emp );
#3.查询工资大于5000的员工,来自于哪些部门的名字
#3.1先查询大于5000的员工所在的部门id
SELECT dept_id FROM emp WHERE salary > 5000; #(1,2 ,null)
#3.2再查询在这些部门id中部门的名字
#Subquery returns more than 1 row 如果是等号
# 如果最后返回的结果是单行单列 使用等号表示
# 如果最后返回的结果是单列多行 使用in表示
SELECT * FROM dept WHERE id IN (SELECT dept_id FROM emp WHERE salary > 5000)
SELECT * FROM emp;
SELECT * FROM dept;
#案例:查询市场部下的员工信息有哪些
#查询出市场部的id值
SELECT id FROM dept WHERE NAME='市场部';
#根据部门的id 找员工表中对于的信息即可
SELECT * FROM emp WHERE dept_id = (SELECT id FROM dept WHERE NAME='市场部');
#案例:查询开发部与财务部所有的员工信息
#查询开发部与财务部 的id值
SELECT id FROM dept WHERE NAME IN ('开发部','财务部');
#查询员工信息
SELECT * FROM emp WHERE dept_id IN ( SELECT id FROM dept WHERE NAME IN ('开发部','财务部') ) ;
#子查询能作为表存在 那么内连接和外连接一定也能够完成
#子查询:作为表存在
#查询出2011年以后入职的员工信息,包括部门名称
#员工信息 部门名称 -> 要多表查询 -> 查询出2011年以后入职
SELECT * FROM dept d , emp e
WHERE d.id = e.dept_id
AND join_date > '2011-01-01' ;
#SELECT * FROM 表1 , (通过子查询的方式查询表)
# WHERE 表1.字段 = 表2.字段
# AND 条件 ;
#子查询
SELECT *
FROM dept d , (SELECT NAME,salary,join_date,dept_id FROM emp) e
WHERE d.id = e.dept_id
AND join_date > '2011-01-01' ;
SELECT * FROM emp;
备份和还原
灾备 : 灾难备份(服务器宕机 磁盘损坏) 一般来说由程序每天自动备份
bin : 可执行文件 或者 批处理目录
命令行的方式
备份格式: mysqldump -u用户名 -p密码 数据库 > 文件的路径
还原格式: SOURCE 导入文件的路径;
注意:还原的时候需要先登录MySQL,并选中对应的数据库
备份的时候 不需要登录到数据库中
> 在系统中 表示 写入到某个文件
mysqldump -uroot -proot 需要备份的数据库名称 > 文件的路径
mysqldump -uroot -proot day03_02 > d:/data.sql
通过命令行到处的数据库 没有创建库的 create database
还原的时候 必须登录到数据里,要选择库
使用source 文件的路径
先创建库 create database 库
使用库 use 库名称
source d:/data.sql
工具的方式
备份
还原
函数
字符串函数
1. 函数:CONCAT(s1,s2...sn)
描述:字符串 s1,s2 等多个字符串合并为一个字符串
实例:SELECT CONCAT("阿", "里", "巴", "巴");
2. 函数:CHAR_LENGTH(str)
描述:返回字符串 str 的字符数(长度)
实例:SELECT CHAR_LENGTH("阿里巴巴");
3. 函数:LENGTH(str)
描述:返回字符串 s 的字节数(长度)
实例:SELECT LENGTH("阿里巴巴") ;
4. 函数:UCASE(s) | UPPER(s)
描述:将字符串转换为大写
实例:SELECT UCASE("Alibaba");
5. 函数:LCASE(s) | LOWER(s)
描述:将字符串转换为小写
实例:SELECT LCASE("ALIBABA");
6. 函数:LOCATE(s1,s)
描述:从字符串 s 中获取 s1 的开始位置
实例:SELECT LOCATE('ao','hhaoheia');
7. 函数:TRIM(str) | LTRIM(str) | RTRIM(str)
描述:字符串去空格
实例:SELECT TRIM(" taikonr");
8. 函数:REPLACE(s,s1,s2)
描述:将字符串 s2 替代字符串 s 中的字符串 s1
实例:SELECT REPLACE('abc','a','x');
9. 函数:SUBSTR(s, start, length)
描述:从字符串 s 的 start 位置截取长度为 length 的子字符串
实例:SELECT SUBSTR("hhhsll", 2, 3);
10. 函数:STRCMP(str1,str2)
描述:比较字符串大小,左大于右时返回1,左等于右时返回0,,左小于于右时返回-1,
实例:SELECT STRCMP("a","b");
日期函数
1. 函数:NOW() | CURDATE() | CURTIME()
描述:获取系统当前日期时间、日期、时间
实例:SELECT NOW();
2. 函数:YEAR(DATE) | MONTH(DATE) | DAY(DATE)
描述:从日期中选择出年、月、日
实例:SELECT YEAR(NOW());
3. 函数:LAST_DAY(DATE)
描述:返回月份的最后一天
实例:SELECT LAST_DAY(NOW());
4. 函数:ADDDATE(DATE,n) | SUBDATE(DATE,n)
描述:计算起始日期 DATE 加(减) n 天的日期
实例:SELECT ADDDATE(NOW(),10);
5. 函数:QUARTER(DATE)
描述:返回日期 DATE 是第几季节,返回 1 到 4
实例:SELECT QUARTER(NOW());
6. 函数:DATEDIFF(d1,d2)
描述:计算日期 d1->d2 之间相隔的天数
实例:SELECT DATEDIFF('2019-08-01','2019-07-01');
7. 函数:DATE_FORMAT(d,f)
描述:按表达式 f的要求显示日期 d
实例:SELECT DATE_FORMAT(NOW(),'%Y-%m-%d');
-- 统计每个员工入职的天数
SELECT DATEDIFF(NOW(),joindate) FROM emp;
-- 统计每个员工的工龄
SELECT DATEDIFF(NOW(),joindate)/365 FROM emp;
-- 查询2011年入职的员工
SELECT * FROM emp WHERE YEAR(joindate) = 2011;
-- 统计入职10年以上的员工信息
SELECT * FROM emp WHERE (DATEDIFF(NOW(),joindate)/365) > 10;
数字函数
1. 函数:ABS(x)
描述:返回 x 的绝对值
实例:SELECT ABS(-1);
2. 函数:CEIL(x) | FLOOR(x)
描述:向上(下)取整
实例:SELECT CEIL(1.5);
3. 函数:MOD(x,y)
描述:返回x mod y的结果,取余
实例:SELECT MOD(5,4);
4. 函数:RAND()
描述:返回 0 到 1 的随机数
实例:SELECT RAND();
5. 函数:ROUND(x)
描述:四舍五入
实例:SELECT ROUND(1.23456);
6. 函数:TRUNCATE(x,y)
描述:返回数值 x 保留到小数点后 y 位的值
实例:SELECT TRUNCATE(1.23456,3);
-- 统计每个员工的工龄,超过半年的算一年
SELECT ROUND(DATEDIFF(NOW(),joindate)/365) FROM emp;
-- 统计每个部门的平均薪资,保留2位小数
SELECT dept_id,TRUNCATE(AVG(salary),2) FROM emp GROUP BY dept_id;
-- 统计每个部门的平均薪资,小数向上取整
CEIL()
-- 统计每个部门的平均薪资,小数向下取整
FLOOR()