MySQL——连接查询(sql92和sql99)

参考链接

  1. https://www.bilibili.com/video/BV12b411K7Zu?p=69

连接查询

含义

连接查询,又称多表查询,当查询的字段来自于多个表时,就会用到连接查询

笛卡尔乘积现象

如果表1有m行,表2有n行,结果=m*n行。发生原因是没有有效的连接条件。

分类

按年代分类
  1. sql92标准:仅仅支持内连接
  2. sql99标准【推荐】:支持内连接+外连接(左外和右外)+交叉连接
按功能分类
内连接
  1. 等值连接
  2. 非等值连接
  3. 自连接
外连接
  1. 左外连接
  2. 右外连接
  3. 全外连接
交叉连接

sql92标准

等值连接
  1. 多表等值连接的结果为多表的交集部分
  2. n表连接,至少需要n-1个连接条件
  3. 多表的顺序没有要求
  4. 一般需要为表起别名
简单查询

比如,“查询员工名和对应的部门名”

SELECT
	last_name,
	department_name
FROM
	employees,
	departments
WHERE
	employees.department_id = departments.department_id;
为表起别名

为表起别名,提高简洁度。如果为表起了别名,则查询的字段就不能使用原来的表名

比如,“查询员工名、工种号、工种名”

SELECT
	last_name,
	e.job_id,
	job_title
FROM
	employees e,
	jobs j
WHERE
	e.job_id=j.job_id;
添加筛选条件

比如,“查询有奖金的员工名、部门名”

SELECT
	last_name,
	department_name
FROM
	employees e,
	departments d
WHERE
	e.department_id=d.department_id
AND
	e.commission_pct IS NOT NULL;

又如,“查询城市名中第二个字符为o的部门名和城市名”

SELECT
	department_name,
	city
FROM
	departments d,
	locations l
WHERE
	d.location_id=l.location_id
AND
	city LIKE '_o%';
添加分组

比如,“查询每个城市的部门个数”

SELECT
	COUNT(*) 个数,
	city
FROM
	departments d,
	locations l
WHERE
	d.location_id=l.location_id
GROUP BY
	city;

又如,“查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资”

SELECT
	department_name,
	d.manager_id,
	MIN(salary)
FROM
	departments d,
	employees e
WHERE
	d.department_id=e.department_id
AND
	commission_pct IS NOT NULL
GROUP BY
	department_name, d.manager_id;
添加排序

比如,“查询每个工种的工种名和员工的个数,并且按员工个数降序”

SELECT
	job_title,
	COUNT(*)
FROM
	employees e,
	jobs j
WHERE
	e.job_id=j.job_id
GROUP BY
	job_title
ORDER BY
	COUNT(*) DESC;
三表连接

比如,“查询员工名、部门名和所在的城市”

SELECT
	last_name,
	department_name,
	city
FROM
	employees e,
	departments d,
	locations l
WHERE
	e.department_id=d.department_id
AND
	d.location_id=l.location_id;
非等值连接

比如,“查询员工的工资和工资级别”

SELECT
	salary,
	grade_level
FROM
	employees e,
	job_grades g
WHERE
	salary BETWEEN g.lowest_sal AND g.highest_sal
自连接

比如,“查询员工名和上级的名称”

SELECT
	e.employee_id,
	e.last_name,
	m.employee_id,
	m.last_name
FROM
	employees e,
	employees m
WHERE
	e.manager_id=m.employee_id;

sql99标准

语法
SELECT
	查询列表
FROM1 别名【连接类型】
JOIN2 别名
ON
	连接条件
WHERE
	筛选条件
GROUP BY
	分组
HAVING
	筛选条件
ORDER BY
	排序列表
分类
  1. 内连接:inner
  2. 外连接:a)左外:left【outer】;2)右外:right【outer】;全外:full【outer】
  3. 交叉连接
内连接
语法
SELECT
	查询列表
FROM1 别名
INNER JOIN2 别名
ON
	连接条件;
分类
  1. 等值
  2. 非等值
  3. 自连接
特点
  1. INNER可以省略
  2. 筛选条件放在WHERE后面,连接条件放在ON后面,提高分离性,便于阅读
等值连接
简单使用

比如,“查询员工名、部门名”

SELECT
	last_name,
	department_name
FROM
	employees e
INNER JOIN
	departments d
ON
	e.department_id=d.department_id;
添加筛选

比如,“查询名字中包含e的员工名和工种名”

SELECT
	last_name,
	job_title,
FROM
	employees e
INNER JOIN
	jobs j
ON
	e.job_id=j.job_id
WHERE
	last_name LIKE "%e%";
添加分组+筛选

比如,“查询部门个数>3的城市名和部门个数”

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

比如,“查询哪个部门的员工个数>3的部门名和员工个数,并按个数降序”

SELECT
	department_name,
	COUNT(*)
FROM
	employees e
INNER JOIN
	departments d
ON
	e.department_id=d.department_id
GROUP BY
	department_name
HAVING
	COUNT(*)>3
ORDER BY
	COUNT(*) DESC;
三表连接

比如,“查询员工名、部门名、工种名,并按部门名降序”

SELECT
	last_name,
	department_name,
	job_title
FROM
	employees e
INNER JOIN
	department d ON e.department_id=d.department_id
INNER JOIN
	jobs j ON e.job_id=j.job_id
ORDER BY
	department_name DESC;
非等值连接

比如,“查询员工的工资级别”

SELECT
	salary,
	grade_level
FROM
	employees e
JOIN
	job_grades g
ON
	e.salary BETWEEN g.lowest_sal AND g.highest_sal;

又如,“查询工资级别的个数>20的个数,并且按工资级别降序”

SELECT
	COUNT(*),
	grade_level
FROM
	employees e
JOIN
	job_grades g
ON
	e.salary BETWEEN g.lowest_sal AND g.highest_sal;
GROUP BY
	grade_level
HAVING
	COUNT(*)>2
ORDER BY
	grade_level DESC;
自连接

比如,“查询员工的名字、上级的名字”

SELECT
	e.last_name,
	m.last_name
FROM
	employees e
JOIN
	employees m
ON
	e.manger_id=m.employee_id;
外连接
应用场景

用于查询一个表中有,另一个表没有的记录

特点
  1. 外连接的查询结果为主表中的所有记录,如果从表中有和它匹配的,则显示匹配的值;如果从表中没有和它匹配的,则显示null;外连接查询结果=内连接结果+主表中有而从表中没有的记录

  2. 左外连接,left join左边的是主表;右外连接,right join右边的是主表

  3. 左外和右外交换两个表的顺序,可以实现同样的效果

  4. 全外连接=内连接的结果+表1中有但表2没有的+表2中有但表1没有的

简单查询

比如,“查询男朋友不在男神表的女神名”

SELECT
	b.name
FROM
	beauty b
LEFT OUTER JOIN
	boys bo
ON
	b.boyfriend_id=bo.id
WHERE
	bo.id IS NULL;

又如,“查询哪个部门没有员工”
左外:

SELECT
	d.*,
	e.employee_id
FROM
	departments d
LEFT OUTER JOIN
	employees e
ON
	d.department_id=e.department_id
WHERE
	e.employee_id IS NULL;

右外:

SELECT
	d.*,
	e.employee_id
FROM
	employees e
RIGHT OUTER JOIN
	departments d
ON
	d.department_id=e.department_id
WHERE
	e.employee_id IS NULL;
全外连接(MySQL不支持)
USE
	girls;
SELECT
	b.*,
	bo.*
FULL OUTER JOIN
	boys bo
ON
	b.boyfriend_id=bo.id;
交叉连接(就是笛卡尔乘积)
SELECT
	b.*,
	bo.*
FROM
	beauty b
CROSS JOIN
	boys bo;

sql92 vs sql99

  1. 功能:sql99支持的较多
  2. 可读性:sql99实现连接条件和筛选条件的分离,可读性较高

你可能感兴趣的:(数据分析,数据库,mysql,sql,DBMS,连接查询)