
视频链接:https://www.bilibili.com/video/BV12b411K7Zu?t=7&p=304
主要内容:
一、连接查询
二、子查询
三、分页查询
四、联合查询
一、连接查询
/*多表查询,多表连接**内连接:**等值连接非等值连接自连接**外连接**:左外连接右外连接全外连接**交叉连接***/一、内连接 P281/*语法:select 查询列表from 表名1 别名1,表名2 别名2...where 等值连接条件特点:1.为解决重名问题,往往会起别名2.表的顺序无要求*/
1.等值连接
/*语法:select 查询列表from 表名1 别名1,表名2 别名2...where 等值连接条件特点:1.为解决重名问题,往往会起别名2.表的顺序无要求*/1.简单的两表连接USE myemployees ;案例:查询员工名和部门名SELECT last_name,department_nameFROM employees e,departments dWHERE e.`department_id`=d.`department_id`;2.添加筛选条件案例1:查询部门编号>100的部门和所在的城市名SELECT `department_name`,`city`FROM departments d,locations lWHERE d.`location_id`=l.`location_id`AND d.`department_id`>100;案例2:查询有奖金的员工名、部门名SELECT `first_name`,`department_name`FROM `employees` e , `departments` dWHERE e.`department_id`=d.`department_id`AND e.commission_pct IS NOT NULL;案例3:查询城市名中的第二个字符为o的部门名和城市名SELECT `department_name`,`city`FROM `departments` d,`locations` lWHERE d.`location_id`=l.`location_id`AND city LIKE '_o%';3.添加分组+筛选案例1:查询每个城市的部门个数SELECT COUNT(*) 部门个数,lo.`city`FROM `departments` d,`locations` loWHERE d.`location_id`=lo.`location_id`GROUP BY lo.`city`;案例2:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资SELECT d.`department_name`,e.`manager_id`,MIN(salary)FROM `departments` d,`employees` eWHERE d.`department_id`=e.`department_id`GROUP BY e.`department_id`;4.添加分组、筛选、排序案例:查询那个部门的员工数>5,并按员工数降序SELECT `department_name`,COUNT(*) 个数FROM `employees` e,`departments` dWHERE e.`department_id`=d.`department_id`GROUP BY e.`department_id`HAVING COUNT(*)>5ORDER BY COUNT(*) DESC;
-------------------SQL99语法---------------------
1.内连接
/*语法:select 查询表名from 表名1 别名**inner join** 表名2. 别名。。。on 连接条件where 筛选group by 分组having 分组后筛选order by 排序*/1.简单的两表连接USE myemployees ;案例:查询员工名和部门名SELECT last_name,department_nameFROM employees e INNER JOIN departments dWHERE e.`department_id`=d.`department_id`;2.添加筛选条件案例1:查询部门编号>100的部门和所在的城市名SELECT `department_name`,`city`FROM departments d INNER JOIN locations lWHERE d.`location_id`=l.`location_id`AND d.`department_id`>100;3.添加分组+筛选案例1:查询每个城市的部门个数SELECT COUNT(*) 部门个数,lo.`city`FROM `departments` d JOIN `locations` loON d.`location_id`=lo.`location_id`GROUP BY lo.`city`;4.添加分组、筛选、排序案例:查询那个部门的员工数>5,并按员工数降序SELECT `department_name`,COUNT(*) 个数FROM `employees` e JOIN `departments` dON e.`department_id`=d.`department_id`GROUP BY e.`department_id`HAVING COUNT(*)>5ORDER BY COUNT(*) DESC;
2.非等值连接
案例:查询部门编号在10-90之间的员工的工资级别,并按级别进行分组SELECT * FROM sal_grade;FROM employees eJOIN sal_grade gON e.salary BETWEEN g.`min_salary` AND g.`max_salary`WHERE e.department_id BETWEEN 10 AND 90GROUP BY g.grade;
3.自连接
案例:查询员工名和对应的领导名SELECT e.`last_name`,m.`last_name`FROM employees eJOIN employees mON e.`manager_id`=m.`employee_id`;
4.外连接
/*说明:查询结果为主表中所有记录,如果从表有匹配项,则显示匹配项;如果从表没有匹配项,则显示null应用场景:一般用于查询主表中有但从表没有的记录特点:1.外连接分主从表,两表顺序不能调换2.左连接的话,左为主表,右链接右为主表语法:SELECT 查询表名FROM 表一 别名LEFT RIGHT OUTER JOIN 表2 别名ON 连接条件WHERE 筛选条件;特点:1.外连接的查询结果 = 内连接的查询结果 + 主表有但从表没有的记录2.区分主从表 left join,左边为主表;right join,右边为主表3.外连接用于查询主表有但从表没有的记录*/USE girls;#案例1:查询所有女神记录,以及对应的男神名称,如果没有对应,显示为null#左连接SELECT b.*,bo.*FROM beauty bLEFT JOIN boys bo ON b.`boyfriend_id` = bo.`id`;#右连接SELECT b.*,bo.*FROM boy boLEFT JOIN beauty b ON b.`boyfriend_id` = bo.`id`;#案例2:哪个女神没有男朋友#左连接SELECT b.*,bo.*FROM beauty bLEFT JOIN boys bo ON b.`boyfriend_id` = bo.`id`WHERE bo.`id` IS NULL;#案例3:查询那个部门没有员工,并显示其部门编号和部门名,并计数SELECT d.`department_id`, d.`department_name`,COUNT(*)FROM departments dLEFT JOIN employees eON D.`department_id`=E.`department_id`WHERE e.`employee_id` IS NULL;
外连接的逻辑,如图:

二、子查询
出现在其他语句的内部的select语句,称为子查询或内查询;里面嵌套其他select语句的查询语句,称为主查询或外查询。
子查询不一定必须出现在select语句内部,只是出现在select语句内部的时候较多!
*分类:*
*单行子查询*
特点:子查询的结果集只有一行一列
*多行子查询*
特点:子查询的结果集有多行一列
按位置分类:
select 后面
要求子查询的结果为单行单列(标量子查询)
FROM后面
要求自持挨训的结果可以为多行多列
WHERE / HAVING 后面
要求:自查询的结果必须为单列
单行子查询
多行子查询
EXISTS后面
要求:子查询结果必须为单列(相关子查询)
*说明:*
1、子查询语句需要放在小括号内,提高代码的阅读性
2、子查询先于主查询执行,一般来讲,主查询会用到子查询的结果
3、如果子查询放在条件中,一般来讲,子查询需要放在条件的右侧
示例:where job_id>(子查询)
不能写成:where (子查询)<job_id
4、单行子查询对应的使用单行操作符:> < >= <= = <>
多行子查询对应的使用多行操作符:in 、any 、all 、not in
LIMIT用来限定查询结果的起始行,以及总行数。
1.放在WHERE后面
a.单行子查询
#案例1:查询Zlotkey的部门编号#步骤1.查询部门编号SELECT department_idFROM employeesWHERE last_name='Zlotkey';#步骤2.查询department_id=1中的员工姓名和工资SELECT last_name,salaryFROM employeesWHERE department_id =(SELECT department_idFROM employeesWHERE last_name='Zlotkey')#案例2:查询工资比公司平均工资高的员工的员工号,姓名和工资#步骤1:先算出公司平均工资,做步骤2的筛选项SELECT AVG(salary)FROM employees;#步骤2:选出工号姓名工资SELECT employee_id,last_name,salaryFROM employeesWHERE salary >(SELECT AVG(salary)FROM employees);#练习题:#案例1:谁的工资比 Abel 高?SELECT last_name,salaryFROM employeesWHERE salary > (SELECT salaryFROM employeesWHERE last_name = 'Abel');#案例2:返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id 和工资SELECT last_name,job_id,salaryFROM employeesWHERE job_id = (SELECT job_idFROM employeesWHERE employee_id = 141)AND salary > (SELECT salaryFROM employeesWHERE employee_id = 143);#案例3:返回公司工资最少的员工的last_name,job_id和salarySELECT last_name,job_id,salaryFROM employeesWHERE salary = (SELECT MIN(salary)FROM employees);#案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资SELECT department_id,MIN(salary)FROM employeesWHERE salary > (SELECT MIN(salary)FROM employeesWHERE department_id = 50);
b.多行子查询
/*in:判断某字段是否在指定列表内x in(10,30,50)any/some:判断某字段是否满足其中任意一个x>any(10,20,60) 就等于 x >min(10,20,60)x = any(10,20,60) 就等于 x in (10,20,60)all : 是否满足所有*/#多行子查询#题目:返回location_id是1400或1700的部门中的所有员工姓名#步骤1SELECT department_idFROM departmentsWHERE location_id IN (1400,1700)#步骤2SELECT last_nameFROM employeesWHERE department_id IN(SELECT department_idFROM departmentsWHERE location_id IN (1400,1700));#题目:返回其它部门中比job_id为‘IT_PROG’部门任一工资低的员工的员工号、姓名、job_id 以及salary#步骤1:选出工资#步骤2:比较```mysqlSELECT salaryFROM employeesWHERE job_id = 'It_PROG';```#步骤2:比较```mysqlSELECT employee_id,last_name,job_id,salaryFROM employeesWHERE job_id !='IT_PROG'AND salary < ANY(SELECT salaryFROM employeesWHERE job_id = 'It_PROG');```#题目:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工 的员工号、姓名、job_id 以及salary#步骤1:选出工资SELECT salaryFROM employeesWHERE job_id = 'It_PROG';#步骤2:比较SELECT employee_id,last_name,job_id,salaryFROM employeesWHERE job_id !='IT_PROG'AND salary < ALL(SELECT salaryFROM employeesWHERE job_id = 'IT_PROG');
2.放在SELECT后面
#案例:查询部门编号是50的员工个数SELECT (SELECT COUNT(*)FROM employeesWHERE department_id = 50)个数;
3.放在FROM后面
#案例:查询每个部门的平均工资的工资级别#步骤1SELECT AVG(salary),department_idFROM employeesGROUP BY department_id;#步骤2:非等值连接,SELECT dep_ag.department_id,dep_ag.ag,g.gradeFROM sal_grade gJOIN (SELECT AVG(salary) ag,department_idFROM employeesGROUP BY department_id) dep_agON dep_ag.ag BETWEEN g.min_salary AND g.max_salary;
4.放在EXISTS后面
#案例1:查询有误张三丰的员工信息SELECT EXISTS(SELECT *FROM employeesWHERE last_name = '张三丰') 有无张三丰;#案例2:查询有没有女朋友的男神信息USE girls;SELECT bo.*FROM boys boWHERE bo.`id` IN(SELECT boyfriend_idFROM beauty b);
子查询经典案例(练习题)
#练习题:#1.查询和 Zlotkey相同部门的员工姓名和工资SELECT last_name,salaryFROM employeesWHERE department_id = (SELECT department_idFROM employeesWHERE last_name = 'Zlotkey');#2.查询工资比公司平均工资高的员工的员工号,姓名和工资SELECT employee_id,last_name,salaryFROM employeesWHERE salary > (SELECT AVG(salary)FROM employees);#3.查询各部门中工资比本部门平均工资高的员工的员工号,姓名和工资SELECT employee_id,last_name,salaryFROM employees eJOIN (SELECT department_id,AVG(salary) agFROM employeesGROUP BY department_id)dep_agON e.department_id =dep_ag.department_idWHERE e.`salary` > dep_ag.ag;#4.查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名SELECT employee_id,last_nameFROM employeesWHERE department_id IN (SELECT department_idFROM employeesWHERE last_name LIKE '%u%');#5.查询在部门的 location id为1700的部门工作的员工的员工号SELECT employee_idFROM employeesWHERE department_id IN (SELECT DISTINCT department_idFROM departmentsWHERE location_id = 1700);#6.查询管理者是King的员工姓名和工资SELECT last_name,salaryFROM employeesWHERE manager_id IN (SELECT employee_idFROM employeesWHERE last_name = 'K_ing');#7.查询工资最高的员工的姓名,要求 firstname和 last name显示为一列,列名为姓名SELECT CONCAT(first_name,last_name)'姓名'FROM employeesWHERE salary = (SELECT MAX(salary)FROM employees);
三、分页查询
/*应用场景:当页面上的数据一页显示不全,则需要分页显示语法:selectfromjoinonwheregroup byhavingorder bylimit 起始条目索引,显示条目数执行顺序:1.from2.join3.on4.where5.group by6.having7.select8.order by9.limit特点:1.起始条目索引从0开始,不写默认从02.参数1:起始条目索引;参数2:显示条目数公式:加入要显示的页数的page,每页显示的条目数为sizeselect *from 表名limit (page-1)*size , size;# -1主要就是因为从计数*/# 案例1 :查询员工信息表的前5条SELECT * FROM employees LIMIT 0,5;等价于SELECT * FROM employees LIMIT 5;# 案例2:查询有奖金的且工资较高的第11名到第20名SELECT * FROM employeesWHERE commission_pct IS NOT NULLORDER BY salary DESCLIMIT 10,10;
四、union联合查询
/*说明:当查询结果来自于多张表,但多张表之间没有关系,这个时候就用联合查询语法:select 查询 from 表1 where 筛选条件unionselect 查询 from 表2 where 筛选条件特点:1.需要注意查询列表的数量一致2.union可以自动去重,加all 可以取消自动去重*/# 案例1:查询所有国家的年龄》20岁的用户信息SELECT * FROM chinese WHERE age>20UNIONSELECT * FROM usa WHERE uage >20;# 案例2:查询所有国家的用户姓名和年龄SELECT uname,uage FROM usaUNIONSELECT 'name',age FROM chinese;# 需要注意查询列表的数量一致# 案例3:union可以自动去重SELECT 1,'haha'UNIONSELECT 1,'haha'UNIONSELECT 1,'haha'UNIONSELECT 1,'haha';# 加all 可以取消自动去重SELECT 1,'haha'UNION ALLSELECT 1,'haha'UNION ALLSELECT 1,'haha'UNION ALLSELECT 1,'haha';
先写这么多,仅供参考,欢迎指点。
如果你有希望实现的内容,或者在过程中遇到了某些困难,欢迎交流探讨!
关注公众号,回复“尚硅谷MySQL”关键字,获取课程配套软件、课件、资料
/如有纰漏 请联系我 十分感谢/

长按图片,点击关注
文章转载自三分稚气,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




