#进阶7:连接查询(有点理解)
/*
一、理解
查询的字段或条件来自于多张表,这个时候则需要使用多表连接查询,简称连接查询
笛卡尔乘积的现象:
表1行数m行,表2行数n行,结果为m*n行
如何产生的?
没有添加连接条件
如何解决?
添加连接条件
如何添加连接条件?sql92语法:
内连接:
等值连接
非等值连接
自连接
外连接:【支持的不太好】mysql中不支持!
左外连接
右外连接
全外连接
sql99语法:内连接:
等值连接
非等值连接
自连接
外连接:
左外连接
右外连接
全外连接【mysql不支持】
*/
#引入案例:查询女神名和对应的男朋友的名称
SELECT `name`,boyname
FROM beauty,boys;
#----------------------------sql92语法-------------------------
#内连接
#一、等值连接
/*语法:
select 查询列表
from 表1 别名1,表2 别名2
where 别名1.字段 = 别名2.字段
and 筛选条件
group by 分组的字段
having 分组后的筛选
order by 排序列表特点:
1、当多表连接时,往往需要为表起别名,为了简化语法
2、多表顺序可以调换
3、n表连接,至少需要n-1个连接条件*/
#1、简单的两表连接
#案例1:查询女神名和对应的男朋友名称
SELECT beauty.`name`,boys.boyname
FROM beauty,boys
WHERE boyfriend_id = boys.`id`;
#2、为表起别名
/*
目的:为了简化表名,解决字段重名的问题
*/
#案例1:查询女神名和对应的男朋友名称
SELECT b.`name`,bo.boyname
FROM beauty b,boys bo
WHERE boyfriend_id = bo.`id`;
#案例2:查询员工名和部门名和部门编号
SELECT last_name,department_name,e.department_id
FROM employees e,departments d
WHERE e.`department_id`=d.`department_id`;
#3、两表顺序是否可以调换
#案例1:查询员工名和部门名和部门编号
SELECT last_name,department_name,e.department_id
FROM departments d, employees e
WHERE e.`department_id`=d.`department_id`;
#4、添加筛选
#案例:查询有奖金的并且邮箱中包含a字符的 工种名和员工名、邮箱、年薪
SELECT `job_title`,`last_name`,`email`,salary*12*(1+IFNULL(commission_pct,0)) 年薪
FROM employees e,jobs j
WHERE e.`job_id`=j.`job_id`
AND email LIKE '%a%' AND commission_pct IS NOT NULL;
#5、添加分组
#案例:查询哪个城市的部门个数>5个
#①查询每个城市的部门个数
SELECT COUNT(*) 个数,city
FROM departments d,locations l
WHERE d.`location_id` = l.`location_id`
GROUP BY city;
#②筛选刚才的结果
SELECT COUNT(*) 个数,city
FROM departments d,locations l
WHERE d.`location_id` = l.`location_id`
GROUP BY city
HAVING 个数>5;
#6、添加排序
#案例:查询每个工种的工种名、平均工资,并按平均工资降序
SELECT job_title,AVG(salary) 平均工资
FROM jobs j,employees e
WHERE j.`job_id`= e.`job_id`
GROUP BY job_title
ORDER BY 平均工资 DESC;
#7、可以实现三表连接
#案例:查询部门名、工种名和员工名,并按年薪降序
SELECT `department_name`,`job_title`,`last_name`
FROM `departments` d,`employees` e,`jobs` j
WHERE d.`department_id` = e.`department_id`
AND e.`job_id`=j.`job_id`
ORDER BY salary*12*(1+IFNULL(commission_pct ,0)) DESC;
#二、非等值连接
#案例:查询每个员工的员工名、工资、工资等级
SELECT last_name,salary,grade
FROM employees e,sal_grade g
WHERE e.`salary` BETWEEN g.`min_salary` AND g.`max_salary`;
#三、自连接
#案例:查询员工名和他的领导的名称、邮箱、工资
SELECT e.last_name,m.last_name,m.email,m.salary
FROM employees e,employees m
WHERE e.`manager_id` = m.`employee_id`;
#--------------------------------SQL99语法--------------------
#内连接
#一、等值连接
/*
语法:
select 查询列表
from 表 别名1
【INNER】 JOIN 表 别名
on 连接条件
where 筛选条件
group by 分组字段
having 分组后筛选
order by 排序列表
特点:
1、sql99语法中将连接条件和筛选条件进行了分离,提高了语句的可读性!
2、两表顺序可以调换
3、n表连接至少n-1个连接条件
*/
#1,简单的两表
#案例1.查询员工名和部门名
SELECT last_name,department_name
FROM employees e
INNER JOIN departments d
ON e.`department_id` = d.`department_id`;
#案例2:查询所有部门的领导信息
SELECT e.*,d.department_id
FROM employees e
JOIN departments d
ON d.`manager_id` = e.`employee_id`;
#2.添加筛选条件
#案例:查询有奖金的员工的工种名和工资
SELECT job_title ,salary
FROM employees e
INNER JOIN jobs j
ON e.`job_id`= j.`job_id`
WHERE commission_pct IS NOT NULL;
#3.添加分组
#案例:查询每个部门的部门名和员工的最低工资,并筛选出最低工资》5000的信息
SELECT department_name,MIN(salary)
FROM employees e
JOIN departments d
ON e.`department_id` = d.`department_id`
GROUP BY department_name
HAVING MIN(salary)>5000;
#4.添加排序
#案例:查询每个城市的部门个数,并且按个数进行降序
SELECT COUNT(*) 个数,city
FROM departments d
JOIN locations l
ON d.`location_id` = l.`location_id`
GROUP BY city
ORDER BY 个数 DESC;
#5.添加三表连接
#案例:查询员工名、部门名、城市,并按员工工资降序
SELECT last_name,department_name,city
FROM employees e
JOIN departments d ON e.`department_id` = d.`department_id`
JOIN locations l ON l.`location_id` = d.`location_id`
ORDER BY salary DESC;
#二、非等值连接
#案例:查询员工的工资、编号、工资等级,并按工资等级分组,查询每个等级的个数
#①查询员工的工资、编号、工资等级
SELECT salary,employee_id,grade
FROM employees e
JOIN sal_grade g
ON e.salary BETWEEN g.`min_salary` AND g.`max_salary`
#②分组
SELECT COUNT(*),grade
FROM employees e
JOIN sal_grade g
ON e.salary BETWEEN g.`min_salary` AND g.`max_salary`
GROUP BY grade
ORDER BY COUNT(*) DESC;
#三、自连接
#案例:查询员工的姓名和工资以及领导姓名和工资
SELECT e.last_name,e.salary,m.last_name,m.salary
FROM employees e
JOIN employees m
ON e.`manager_id` = m.`employee_id`;
#外连接