(五)连接查询(SQL99标准)、子查询、分页查询、联合查询

一、连接查询(SQL99标准)

1、含义:当要查询的数据来自多张表时要使用连接查询

2、语法:

select 查询列表
from 表1 别名 
【连接类型】 join 表2 别名 
on 连接条件
【where 筛选条件】
【group by 分组】
【having 筛选条件】
【order by 排序列表】

注意:SQL99标准支持以下连接方式:

#1内连接

#2外连接:左外、右外、全外连接

#3交叉连接(很少用到)

3、内连接:

案例一:查询部门个数>3的城市名和部门个数(分组函数+分组查询)

上图可以看出两个表之间的关系

SELECT COUNT(*),l.`city`
FROM departments d
INNER JOIN locations l ON d.`location_id`=l.`location_id`
GROUP BY l.`city`
HAVING COUNT(*)>3;

案例二:查询员工名、部门名、工种名,并按部门名降序(添加三表连接)

SELECT last_name,department_name,job_title
FROM employees e
INNER JOIN departments d ON e.`department_id`=d.`department_id`
INNER JOIN jobs j ON e.`job_id`=j.`job_id`
ORDER BY d.`department_name` DESC;

注意:根据上面两个案例可以看出内连接时连接类型使用INNER(可省略)

4、外连接(左外、右外连接)

①用到的库信息:

②区分左、右外连接:

③左外连接:

案例:查询男朋友不在男生表中的女神名

SELECT b.`name`
FROM beauty b
LEFT JOIN boys bo ON b.`boyfriend_id`=bo.`id`;

注意:左外连接类型使用LEFT  OUTER ,其中OUTER可以省略

④右外连接:

案例:查询男朋友不在男生表中的女神名

SELECT b.`name`
FROM boys bo
RIGHT JOIN beauty b ON bo.`id`=b.`boyfriend_id`;

注意:右外连接类型使用RIGHT  OUTER ,其中OUTER可以省略

⑤区分内外连接:

      

二、子查询

1、含义:SQL语句中嵌套其它完整的SQL语句

2、分类:

select后: 标量子查询(结果集只有一行一列)

from后:表子查询(多行多列)

where或having后:标量子查询()、列子查询(一列多行)、行子查询(一行多列)

exists后面:相关子查询、表子查询

注意:

①子查询要放在小括号中,且子查询不需要添加分号

②标量子查询:一般搭配单行操作符使用(> < >= <= = <>)

③列子查询:一般搭配多行操作符使用(in、any/some、all)

3、WHERE或HAVING后面的子查询:

①标量子查询:

案例1:谁的工资比 Abel 高? (子查询)

step1:查询Abel的工资

USE myemployees;
SELECT e.salary Abel的工资
FROM employees e
WHERE e.last_name='Abel';

step2:将step1的结果当作子查询嵌套在step中

SELECT last_name
FROM employees e
WHERE e.`salary`>(
	SELECT e.salary Abel的工资
	FROM employees e
	WHERE e.last_name='Abel'
);

运行结果:

案例2:返回job_id与141号员工相同,salary比143号员工多的员工 姓名,job_id(多个子查询)

step1:查询141号员工的job_id

SELECT e.job_id
FROM employees e
WHERE e.`employee_id`=141;

step2:143号员工的工资

SELECT e.salary
FROM employees e
WHERE e.`employee_id`=143;

step3:将step1、step2的结果嵌套到step3中

SELECT e.last_name,e.job_id
FROM employees e
WHERE e.`job_id`=(
	SELECT e.job_id
	FROM employees e
	WHERE e.`employee_id`=141
)AND e.salary > (
	SELECT e.salary
	FROM employees e
	WHERE e.`employee_id`=143	
);

案例3:查询最低工资大于50号部门最低工资的部门id和其最低工资(分组查询+HAVING后子查询)

SELECT department_id,MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary)>( #筛选的时候注意是where还是having
	SELECT MIN(salary)
	FROM employees
	WHERE department_id=50
);

②列子查询:

案例:返回location_id是1400或1700的部门中的所有员工姓名

SELECT e.last_name
FROM employees e
WHERE e.`department_id` IN(
	SELECT d.department_id
	FROM departments d
	WHERE d.`location_id` IN(1400,1700)
);

注意:IN 等价于=ANY ( ) , NOT IN 等价于<> ALL( ) 

③行子查询:

案例:查询员工编号最小并且工资最高的员工信息

SELECT * 
FROM employees
WHERE (employee_id,salary)=(
	SELECT MIN(employee_id),MAX(salary)
	FROM employees
);

SELECT *
FROM employees
WHERE employee_id=(
	SELECT MIN(employee_id)
	FROM employees
)AND salary=(
	SELECT MAX(salary)
	FROM employees
);

4、FROM后面的子查询

含义:FROM后面跟的是表,所以子查询的结果也应该是一张表。

注意:FROM后面的子查询必须要起别名

案例:查询每个部门的平均工资的工资等级

step1:查询每个 部门的平均工资和部门编号

SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id;

运行结果:

注意:运行结果是一张表

step2:根据step1得出的表,判断工资等级

SELECT  ag_dep.*,g.`grade_level`
FROM (
	SELECT AVG(salary) ag,department_id
	FROM employees
	GROUP BY department_id
) ag_dep
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;

5、SELECT后面子查询(仅支持标量子查询)

案例:查询每个部门的员工个数 

SELECT d.*,(
	SELECT COUNT(*)
	FROM employees e
	WHERE d.`department_id`=e.department_id
)个数
FROM departments d;

6、EXITS后面的子查询

语法:(返回值仅为1/0,当括号中表不为空时返回1,否则返回0)

SELECT EXISTS(SELECT * FROM employees);

案例:查询有员工的部门名

SELECT department_name
FROM departments d
WHERE EXISTS(
	SELECT *
	FROM employees e
	WHERE e.`department_id`=d.`department_id`
);

三、分页查询

1、含义:从一张表中选出连续几行数据要用到分页查询。

2、语法:

SELECT 查询列表
FROM 表
【JOIN TYPE JOIN 表2
ON 连接条件
WHERE 筛选条件
GROUP BY 分组字段
HAVING 分组后的筛选
ORDER BY 排序的字段】
LIMIT 【OFFSET,】size;

注意:OFFESET:起始索引(默认从0开始) SIZE:总行数

案例1:有奖金的员工信息,显示工资较高的前10名

step1:降序排列有奖金的员工信息

SELECT e.*
FROM employees e
WHERE e.`commission_pct` IS NOT NULL
ORDER BY e.`salary` DESC;

step2:将员工信息的前十条筛选出来

SELECT e.*
FROM employees e
WHERE e.`commission_pct` IS NOT NULL
ORDER BY e.`salary` DESC
LIMIT 0,10;

案例2:已知页数page和每页的行数size,写出通式

SELECT 查询列表
​FROM 表
​LIMIT (page-1)*size,size;

四、联合查询

1、优点:当多张表之间没有连接条件时,使用UNION(联合查询)很方便。

2、语法:

查询语句1
UNION
查询语句2
UNION
……

注意:

①要求多条查询语句的查询列数一致且每条查询语句都要完整(可单独执行),非最后一条查询条件不需要添加分号

最终显示的字段名称是第一条查询条件中所查询的内容,要保证所有查询语句所查询的内容一致且数目相等

UNION查询默认去重,可使用UNION ALL来避免去重

案例1:查询部门编号>90或邮箱包含a的员工信息

SELECT * FROM employees  WHERE email LIKE '%a%'
UNION
SELECT * FROM employees  WHERE department_id>90;

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

复习整理,如有错误请指出。

原文地址:https://www.cnblogs.com/ldu-xingjiahui/p/12594040.html