MySQL数据库学习之去重与连接查询详解
作者:世界尽头与你 发布时间:2024-01-20 19:16:16
1.去重
示例表内容参考此文章
有些 MySQL 数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需要删除这些重复的数据。
例如:去重显示岗位信息:
mysql> select distinct job from emp;
+-----------+
| job |
+-----------+
| CLERK |
| SALESMAN |
| MANAGER |
| ANALYST |
| PRESIDENT |
+-----------+
5 rows in set (0.02 sec)
另一个示例:联合去重,查找部门和岗位的独有信息:
mysql> select distinct job,deptno from emp;
+-----------+--------+
| job | deptno |
+-----------+--------+
| CLERK | 20 |
| SALESMAN | 30 |
| MANAGER | 20 |
| MANAGER | 30 |
| MANAGER | 10 |
| ANALYST | 20 |
| PRESIDENT | 10 |
| CLERK | 30 |
| CLERK | 10 |
+-----------+--------+
9 rows in set (0.00 sec)
另一个示例:现在我们想统计一下工作岗位的数量,结合使用count函数:
mysql> select count(distinct job) from emp;
+---------------------+
| count(distinct job) |
+---------------------+
| 5 |
+---------------------+
1 row in set (0.00 sec)
2.连接查询
我们已经学会了如何在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据。
JOIN 按照功能大致分为如下三类:
INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。
LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录。
RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。
多表连接的机制是:从其中一个表中取出每一条数据,从另一个表中的数据行进行匹配。这就涉及到了效率控制问题
使用where进行多表连接查询
现在我们来演示一个例子:取出每个员工的名字和部门名字:
mysql> select ename,dname
-> from emp,dept
-> where emp.deptno = dept.deptno;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)
上面的sql语句实际上效率很低,我们尝试进行优化(给表起别名):(sql92语法)
mysql> select e.ename,d.dname
-> from emp e,dept d
-> where e.deptno = d.deptno;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)
注意:表的连接次数越多,效率越低,请尽量减少表的连接次数!
内连接 - 等值连接
还是上面的例子,取出每个员工的名字和部门名字:(sql99语法)
内连接,我们使用inner
mysql> select e.ename,d.dname
-> from emp e
-> inner join
-> dept d
-> on
-> e.deptno = d.deptno;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)
sql99的优点是:表的连接是独立的,不占用where的位置。使sql语句整体更加清晰
内连接 - 非等值连接
案例:找出每个员工的薪资等级,要求显示员工名,薪资,薪资等级
mysql> select
-> e.ename,e.sal,s.grade
-> from
-> emp e
-> inner join
-> salgrade s
-> on
-> e.sal between s.losal and s.hisal;
+--------+---------+-------+
| ename | sal | grade |
+--------+---------+-------+
| SMITH | 800.00 | 1 |
| ALLEN | 1600.00 | 3 |
| WARD | 1250.00 | 2 |
| JONES | 2975.00 | 4 |
| MARTIN | 1250.00 | 2 |
| BLAKE | 2850.00 | 4 |
| CLARK | 2450.00 | 4 |
| SCOTT | 3000.00 | 4 |
| KING | 5000.00 | 5 |
| TURNER | 1500.00 | 3 |
| ADAMS | 1100.00 | 1 |
| JAMES | 950.00 | 1 |
| FORD | 3000.00 | 4 |
| MILLER | 1300.00 | 2 |
+--------+---------+-------+
14 rows in set (0.01 sec)
内连接 - 自连接
案例:查询员工的上级领导,要求显示员工名和对应的领导名
我们可以发现,员工和领导的关系在一张表中,此时需要用到自连接(技巧:一张表看成两张表)
mysql> select
-> a.ename as '员工名',b.ename as '领导名'
-> from emp a
-> join emp b
-> on
-> a.mgr = b.empno;
+-----------+-----------+
| 员工名 | 领导名 |
+-----------+-----------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
+-----------+-----------+
13 rows in set (0.00 sec)
外连接 - 左右外连接
外连接与内连接的区别是,外连接没有匹配成功的某一个表的记录也会被取出
案例:查找员工的部门信息。要求部门即使没有员工也要查出
mysql> select
-> e.ename,d.dname
-> from emp e
-> right join dept d
-> on
-> e.deptno = d.deptno;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
| NULL | OPERATIONS |
+--------+------------+
15 rows in set (0.00 sec)
同样的,如果是左外连接,将查询出左表的全部数据,使用left join关键字即可
外连接的查询结果条数一定是 >= 内连接的查询结果条数
三表连接
更为复杂的情况是,群表连接
我们来看一个案例:
找出每个员工的部门名称及工资等级。要求显示员工名,部门名,薪资,薪资等级
mysql> select
-> e.ename,e.sal,d.dname,s.grade
-> from emp e
-> join dept d
-> on e.deptno = d.deptno
-> join salgrade s
-> on e.sal between s.losal and s.hisal;
+--------+---------+------------+-------+
| ename | sal | dname | grade |
+--------+---------+------------+-------+
| SMITH | 800.00 | RESEARCH | 1 |
| ALLEN | 1600.00 | SALES | 3 |
| WARD | 1250.00 | SALES | 2 |
| JONES | 2975.00 | RESEARCH | 4 |
| MARTIN | 1250.00 | SALES | 2 |
| BLAKE | 2850.00 | SALES | 4 |
| CLARK | 2450.00 | ACCOUNTING | 4 |
| SCOTT | 3000.00 | RESEARCH | 4 |
| KING | 5000.00 | ACCOUNTING | 5 |
| TURNER | 1500.00 | SALES | 3 |
| ADAMS | 1100.00 | RESEARCH | 1 |
| JAMES | 950.00 | SALES | 1 |
| FORD | 3000.00 | RESEARCH | 4 |
| MILLER | 1300.00 | ACCOUNTING | 2 |
+--------+---------+------------+-------+
14 rows in set (0.00 sec)
再来看一个更复杂的情况:
找出每个员工的部门名称及工资等级及领导名称。要求显示员工名,部门名,领导名,薪资,薪资等级
mysql> select
-> e.ename,e.sal,d.dname,s.grade,l.ename
-> from emp e
-> join dept d
-> on e.deptno = d.deptno
-> join salgrade s
-> on e.sal between s.losal and s.hisal
-> left join
-> emp l
-> on e.mgr = l.empno;
+--------+---------+------------+-------+-------+
| ename | sal | dname | grade | ename |
+--------+---------+------------+-------+-------+
| SMITH | 800.00 | RESEARCH | 1 | FORD |
| ALLEN | 1600.00 | SALES | 3 | BLAKE |
| WARD | 1250.00 | SALES | 2 | BLAKE |
| JONES | 2975.00 | RESEARCH | 4 | KING |
| MARTIN | 1250.00 | SALES | 2 | BLAKE |
| BLAKE | 2850.00 | SALES | 4 | KING |
| CLARK | 2450.00 | ACCOUNTING | 4 | KING |
| SCOTT | 3000.00 | RESEARCH | 4 | JONES |
| KING | 5000.00 | ACCOUNTING | 5 | NULL |
| TURNER | 1500.00 | SALES | 3 | BLAKE |
| ADAMS | 1100.00 | RESEARCH | 1 | SCOTT |
| JAMES | 950.00 | SALES | 1 | BLAKE |
| FORD | 3000.00 | RESEARCH | 4 | JONES |
| MILLER | 1300.00 | ACCOUNTING | 2 | CLARK |
+--------+---------+------------+-------+-------+
14 rows in set (0.00 sec)
来源:https://blog.csdn.net/Gherbirthday0916/article/details/125956597
猜你喜欢
- 简述1.pythonpython作为一门解释型脚本语言,它有三种发布方式:文件 : 源码文件,运行需要使用者安装Python环境并且安装依赖
- 最近发现了一个宝藏动态可视化库,非常简单,即使是小白也能轻松上手。这个库就是motionchart,它能够用 pandas 的 datafr
- 目录1.任务要求2.简单设计3.模块实现4.总结由于一些小原因,被迫开始了tkinter一次实战演练。在此做一些记录,总结以及给自己留一些轮
- Python实战系列用于记录实战项目中的思路,代码实现,出现的问题与解决方案以及可行的改进方向本文为第2篇–200行Python代码实现20
- 查看版本号sqlplus / as sysdba>select * from v$version;备份orcl数据库export OR
- Python从MySQL数据库中导出csv文件处理csv文件导入MySQL数据库import pymysqlimport csvimport
- 大家好,我是丁小杰!今天和大家分享Pandas中四种有关数据透视的通用函数,在数据处理中遇到这类需求时,能够很好地应对。pandas.mel
- 本文只考虑模板中的字符串,不考虑字符串中带标签的情况。模板中的字符串文字不会自动转义,因为这里默认模板的作者已经正确书写模板的内容。{{ d
- 概述在之前的风资源分析文章中,有提到过用widrose包来进行玫瑰图的绘制,目前的可视化绘图包有很多,但是最基础和底层的,本人认为还是mat
- 一.摘要做接口自动化测试时,常常需要使用python发送一些json内容的接口报文,如果使用urlencode对内容进行编码解析并发送请求,
- 读取一个已经保存了的字典f = open('dict_th','r')a = f.read()dict_hi
- 首先这个是7米当时问我一个问题,不过可惜我不知道怎么解决,后来知道解决方法很简单,只是添加了一个margin-top:-1em就
- 目录range函数的使用第一种创建方式第二种创建方式第三种创建方式判断指定的数有没有在当前序列中循环结构总结range函数的使用作为循环遍历
- 一、前提条件安装了Fiddler了(用于抓包分析)谷歌或火狐浏览器如果是谷歌浏览器,还需要给谷歌浏览器安装一个SwitchyOmega插件,
- 本文实例讲述了python判断windows系统是32位还是64位的方法。分享给大家供大家参考。具体分析如下:通常64的windows系统p
- 呵呵,我之前也写过一个类似的模板替换功能.>> 已实现:>、<、>=、<=、=、==等简单的运算>
- python框架有很多,例如:Flask,Django,FastAPI 等。本文将使用 Flask 来编写 API 接口。安装Flask首先
- 1、简介FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 3.6+ 并基于标准的 Pyth
- 如下所示:sudo easy_install requests出现如图所示信息done即可愉快的使用 requests了来源:https:/
- Python是静态作用域语言,但是它自身是一个动态语言。在Python中变量的作用域是由变量在代码中的位置决定的,与C语言有些相似,但不是完