连接查询,又称多表查询,当查询的字段来自于多个表时,就会用到连接查询
如果表1有m行,表2有n行,结果=m*n行。发生原因是没有有效的连接条件。
比如,“查询员工名和对应的部门名”
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;
SELECT
查询列表
FROM
表1 别名【连接类型】
JOIN
表2 别名
ON
连接条件
WHERE
筛选条件
GROUP BY
分组
HAVING
筛选条件
ORDER BY
排序列表
SELECT
查询列表
FROM
表1 别名
INNER JOIN
表2 别名
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;
用于查询一个表中有,另一个表没有的记录
外连接的查询结果为主表中的所有记录,如果从表中有和它匹配的,则显示匹配的值;如果从表中没有和它匹配的,则显示null;外连接查询结果=内连接结果+主表中有而从表中没有的记录
左外连接,left join左边的是主表;右外连接,right join右边的是主表
左外和右外交换两个表的顺序,可以实现同样的效果
全外连接=内连接的结果+表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;
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;