#进阶六:连接查询
/*
含义:又称为多表查询
笛卡尔乘积现象:表1有m行,表2有n行,结果m*n行
如何发生:没有有效的连接条件
如何避免:添加上有效的连接条件
分类:
按年代分类
sql92标准:仅仅支持内连接
sql99标准【推荐】:支持所有的内连接+外连接(左外和右外)+交叉连接
按功能分类:
内连接:等值连接 非等值连接 自连接
外连接:右外连接 左外连接 全外连接
交叉连接
*/
SELECT * FROM beauty;
SELECT * FROM boys;
SELECT NAME,`boyName` FROM `boys`,`beauty`
WHERE `beauty`.boyfriend_id=`boys`.id;
#一.sql92表最近
#1.等值连接
/*
①多表等值连接的结果为多表的交集部分
②n表连接,至少需要n-1个连接条件
③多表的顺序无要求
④一般需要为表起别名
⑤可以搭配前面介绍的所有查询子句使用,比如排序,分组,筛选
*/
#案例1:查询女神名和对应的男神名
SELECT NAME,`boyName`
FROM `boys`,`beauty`#涉及的表有哪些
WHERE `beauty`.boyfriend_id=`boys`.id;
#案例2:查询员工名和对应的部门名
SELECT `last_name`,`department_name`
FROM `employees`,`departments`
WHERE employees.`department_id`=departments.`department_id`;
#2.为表起别名
#①提高语句简洁度
#②区分多个重名的字段
#③如果为表起了别名,则查询的字段就不能用原来的表名去限定,只能用别名
#查询员工名、工种号、工种名
SELECT `last_name`,e.`job_id`,`job_title` #这里不能再写employees.`job_id`
FROM `employees` e,`jobs` j
WHERE j.`job_id`=e.`job_id`;
#两个表的顺序可以调换
SELECT last_name,e.job_id,j.job_title
FROM jobs AS j,employees AS e
WHERE e.job_id=j.`job_id`;
#4、可以加筛选 -------AND
#案例:查询有奖金的员工名、部门名
SELECT `last_name`,`department_name`
FROM `employees` e,`departments` d
WHERE e.`department_id`=e.`department_id`
AND e.`commission_pct` IS NOT NULL;
#案例2:查询出城市名中第二个字符为o的部门名和城市名
SELECT `department_name`,`city`
FROM `departments` d,`locations` l
WHERE d.`location_id`=l.`location_id`
AND `city`LIKE'_o%';
#5、加分组
#案例1:查询每个城市的部门个数
SELECT `city`,COUNT(*) 个数
FROM `locations` l,`departments` d
WHERE l.`location_id`=d.`location_id`
GROUP BY `city`;
#案例2:查询有奖金的每个部门的部门名和部门的领导编号,和该部门的最低工资
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`;
#6、加排序
#案例:查询每个工种的工种名和员工个数,按员工个数降序
SELECT `job_title`,COUNT(*) 个数
FROM `jobs` j,`employees` e
WHERE j.`job_id`=e.`job_id`
GROUP BY `job_title`
ORDER BY 个数 DESC;
#7、实现三表连接
#案例:查询员工名、部门名和所在的城市 (城市名中包含‘s’,department_id降序排列..)
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`
AND city LIKE'%s%'
ORDER BY `department_name` DESC;
#---------------------------------------------------------------------------------------
#2、非等值连接
#案例1:查询员工的工资和工资级别
#创建工资级别
CREATE TABLE job_grades
(grade_level VARCHAR(3),
lowest_sal INT,
highest_sal INT);
INSERT INTO job_grades
VALUES ('A', 1000, 2999);
INSERT INTO job_grades
VALUES ('B', 3000, 5999);
INSERT INTO job_grades
VALUES('C', 6000, 9999);
INSERT INTO job_grades
VALUES('D', 10000, 14999);
INSERT INTO job_grades
VALUES('E', 15000, 24999);
INSERT INTO job_grades
VALUES('F', 25000, 40000);
SELECT * FROM `job_grades`;
SELECT `salary`,`grade_level`
FROM `employees` e,`job_grades` j
WHERE salary BETWEEN j.`lowest_sal` AND j.`highest_sal`
AND grade_level='A';#可以追加更多条件
#3.自连接 **********************************************8
#案例:查询员工名和上级的名称
SELECT e.`last_name`,e.`employee_id`,m.`employee_id`,m.`last_name`
FROM `employees` e,`employees` m
WHERE e.`manager_id`= m.`employee_id`;
#练习题:查询员工的job_id中包含 a 和e,并且a在e的前面
SELECT job_id FROM employees
WHERE job_id LIKE '%a%e%';