MySQL学习记录 - 06-连接查询

根据尚硅谷的视频教程学习MySQL,学习记录-06-连接查询
所有操作开始之前,建议先打开对应的库:

USE 库名;
USE employees;

=> 分类:
多表查询,当查询字段来自于多个表时,就会用到连接查询

按年份分类:
=>sql92标准: 仅仅支持内连接
=>sql99标准【推荐】:支持内连接+外连接(左外+右外)+交叉连接

按照功能分类:
=>内连接:等值连接、非等值连接、自连接
=>外连接:左外连接、右外连接、全外连接
=>交叉连接

一、sql92标准

=> 语法:

SELECT 查询列表
FROM1 别名,表2 别名
WHERE 连接条件 (以及其他筛选条件)

=> 案例:

  1. 等值连接

案例1:查询员工名和对应的部门名

SELECT last_name, department_name
FROM employees, departments
WHERE employees.department_id = departments.department_id;

案例2:查询员工名、工种号、工种名【为表起别名,区分多个重名字段】

SELECT last_name,e.job_id, job_title
FROM employees e, jobs j
WHERE e.job_id = j.job_id;

但是,起了别名之后,不能识别原始表名称,不能使用原始表名限定

SELECT last_name,employees.job_id, job_title
FROM employees e, jobs j
WHERE e.job_id = j.job_id;
结果报错

案例3:【两个表的顺序可以调换】

SELECT last_name,e.job_id, job_title
FROM jobs j, employees e
WHERE e.job_id = j.job_id;

案例4: 【添加筛选】查询有奖金的员工名、部门名

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

案例5:【添加分组】查询每个城市的部门个数

SELECT l.city, COUNT(DISTINCT d.department_id) as num
FROM locations l, departments d
WHERE l.location_id = d.location_id
GROUP BY l.city

案例6:【分组、筛选】查询有奖金的每个部门的部门名、部门领导编号和该部门的最低工资

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

案例7: 【添加排序】查询每个工种的工种名、员工个数,按照员工个数降序

SELECT job_title, COUNT(DISTINCT e.employee_id) 个数
FROM jobs j, employees e
WHERE j.job_id = e.job_id
GROUP BY job_title
ORDER BY 个数 DESC;

案例8:【实现3个表连接】查询员工名、部门名、所在城市,城市以S开头

SELECT e.last_name, d.department_name, l.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 e.last_name;

等值连接总结:

  1. 多表等值连接的结果为多表的交集部分
  2. n表连接,至少需要n-1个连接条件
  3. 多表的顺序没有要求
  4. 一般需要为表起别名
  5. 可以搭配前面的所有子句一起使用:筛选、分组、排序等
  1. 非等值连接

案例1: 查询员工的工资和工资级别,按照薪资从高到低排序

SELECT salary, grade 
FROM employees e, sal_grade s
WHERE e.salary >=min_salary AND e.salary < max_salary
ORDER BY salary DESC;
或者使用Between语句
SELECT salary, grade
FROM employees e, sal_grade s
WHERE salary BETWEEN min_salary AND max_salary
ORDER BY salary DESC;
  1. 自连接

案例1: 查询员工名、上级的名称

SELECT e.last_name, e.manager_id, m.last_name as manager
FROM employees e, employees m
WHERE e.manager_id = m.employee_id
  1. 小节练习
    练习1:查询90号部门员工的job_id 和 90号部门的location_id;
SELECT DISTINCT job_id, location_id
FROM employees e, departments d
WHERE e.department_id = d.department_id
AND e.department_id = 90;

练习2:选择所有有奖金的员工的 名字、部门名、location_id和城市

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

练习3: 选择city在Toronto工作的员工的名字、工种、部门编号、部门名称

SELECT last_name, job_id, e.department_id, d.department_name
FROM employees e, departments d, locations l
WHERE e.department_id = d.department_id AND d.location_id = l.location_id
AND city = 'Toronto';

练习4: 查询每个国家下的部门个数大于2的国家编号

SELECT country_id, COUNT(*) as 部门个数
FROM departments d, locations l
WHERE d.location_id = l.location_id
GROUP BY l.country_id
HAVING COUNT(*)>2;

练习5: 查询每个工种、每个部门的部门名、工种名和最低工资

SELECT department_name, job_title, MIN(salary)
FROM jobs j, employees e,departments d
WHERE j.job_id = e.job_id AND e.department_id = d.department_id
GROUP BY d.department_name, e.job_id;

练习6:选择指定员工的姓名、员工号,以及对应管理者的姓名和员工号,员工姓名为 kochhar 101

SELECT e.last_name employee, e.employee_id as "Emp#",
m.last_name manager, m.employee_id as "Mgr#"
FROM employees e, employees m
WHERE e.manager_id = m.employee_id
AND e.last_name = 'kochhar'

二、sql99标准

=> 语法:

SELECT 查询列表
FROM1 别名 【连接类型】 
JOIN2 别名
ON 连接条件
【WHERE 筛选条件 GROUP BY 分组 HAVING 筛选 ORDER BY 排序】

连接类型:inner join / left join / right join / full join / cross (交叉连接)

=> 案例:

  1. 内连接 - 等值连接

案例1:查询员工名、部门名

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

案例2:【添加筛选】查询名字中包含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:【添加分组、筛选】查询部门个数大于3的城市名、部门个数

SELECT l.city, COUNT(*) as 部门个数
FROM departments d
INNER JOIN locations l
ON d.location_id = l.location_id
GROUP BY l.city
HAVING count(*)>3;

案例4:【添加排序】查询哪个部门的员工个数>3的部门名、员工个数,并按照员工个数降序

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

案例5: 【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 department_name DESC;
  1. 内连接 - 非等值连接

特点

  1. 可以添加排序、分组、筛选
  2. inner可以省略
  3. 筛选条件放在WHERE后,连接语句在ON后
  4. INNER JOIN连接和92语法中的等值连接一样,查询交集结果

案例1:查询员工的工资级别

SELECT salary, grade
FROM employees e
INNER JOIN sal_grade
ON e.salary BETWEEN min_salary AND max_salary;

案例2:查询每个工资级别个数大于3的个数,并且按照工资级别降序

SELECT grade, count(*)
FROM employees e
INNER JOIN sal_grade
ON e.salary BETWEEN min_salary AND max_salary
GROUP BY grade
HAVING count(*) > 3
ORDER BY grade DESC;
  1. 内连接 - 自连接

案例1:查询姓名中包含K的员工名、上级的名称

SELECT e.last_name, m.last_name as manager
FROM employees e
INNER JOIN employees m
ON e.manager_id = m.employee_id
WHERE e.last_name LIKE '%k%';
  1. 外连接: 查询一个表中有,另外一个表中没有的记录
  1. 外连接的查询结果为主表中的所有记录
    如果从表中有和主表匹配的,则显示匹配值
    如果从表中没有和主表匹配的,则显示NULL
    外连接查询结果 = 内连接的结果 + 主表有而从表没有的记录
  2. 左外链接:LEFT JOIN左侧的是主表
    右外连接:RIGHT JOIN 右侧的是主表
  3. 左外和右外交换两个表的顺序,可以实现同样的效果。
  4. 全外连接查询结果 = 内连接的结果 +表1有但是表2没有的+表2有但是表1 没有的

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

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

案例2:查询哪个部门没有员工

SELECT department_name
FROM departments d
LEFT JOIN employees e
ON e.department_id = d.department_id
WHERE e.employee_id IS NULL;
右外连接
SELECT department_name
FROM employees e
RIGHT JOIN departments d
ON e.department_id = d.department_id
WHERE e.employee_id IS NULL;
  1. 全外连接 - 目前99sql不支持
SELECT *
FROM beauty b
FULL JOIN boys bo
ON b.boyfriend_id = bo.id
  1. 交叉连接 - 笛卡尔积结果
SELECT *
FROM beauty b CROSS JOIN boys bo;

三、总结与习题

功能:sql99 支持更多
可读性:sql99将连接条件与其他筛选条件分开体现,可读性更高

练习1:查询哪个城市没有部门

SELECT city
FROM locations l
LEFT JOIN departments d
ON l.location_id = d.location_id
WHERE d.department_id IS NULL

练习2:查询部门名为SAL或IT的员工信息

SELECT d.department_id,d.department_name, e.*
FROM employees e
RIGHT JOIN departments d
ON e.department_id = d.department_id
WHERE department_name IN ('SAL','IT');
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL中,全连接查询语句可以使用内连接和外连接来实现。内连接是指连接两张表时,只查询能够匹配上连接条件的数据,没有匹配的数据将不会被查询出来。而外连接则是查询两张表中所有的数据,无论是否匹配上连接条件。在MySQL中,可以使用关键字"JOIN"来表示连接操作,"INNER JOIN"表示内连接,"LEFT JOIN"表示左外连接,"RIGHT JOIN"表示右外连接。下面是一个例子: SELECT * FROM table1 INNER JOIN table2 ON table1.column = table2.column; 这个查询语句将会通过内连接查询表table1和table2中根据column列进行匹配的数据。如果你想使用外连接来进行全连接查询,可以将"INNER JOIN"换成"LEFT JOIN"或"RIGHT JOIN"。例如: SELECT * FROM table1 LEFT JOIN table2 ON table1.column = table2.column; 这个查询语句将会通过左外连接查询表table1和table2的所有数据,并将根据column列进行匹配的数据连接起来。如果没有匹配的数据,则会在结果中显示NULL值。同理,你也可以使用"RIGHT JOIN"来实现右外连接。 总结起来,全连接查询语句可以通过使用内连接或外连接来实现,使用"JOIN"关键字来表示连接操作,根据需要选择合适的连接类型即可。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [MySQL学习笔记2-高级查询与存储.md](https://download.csdn.net/download/weixin_52057528/88240999)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [MySql中的连接查询](https://blog.csdn.net/qq_57005976/article/details/129006433)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值