mysql连接查询


tags: 知识拓展
categories: MySQL
top: false
copyright: true
abbrlink: 1643719980
description: 在实际开发中,大部分的情况下都不是从单表中查询数据,一般都是多张表联合查询取出最终的结果。在实际开发中,一般一个业务都会对应多张表,比如:学生和班级,起码两张表。


查询结果

关于查询结果集的去重?distinct关键字去除重复记录

mysql> select distinct job from emp;
±----------+
| job |
±----------+
| CLERK |
| SALESMAN |
| MANAGER |
| ANALYST |
| PRESIDENT |
±----------+

select ename,distinct job from emp;

以上的sql语句是错误的。
记住:distinct只能出现在所有字段的最前面。

mysql> select distinct deptno,job from emp order by deptno;
±-------±----------+
| deptno | job |
±-------±----------+
| 10 | CLERK |
| 10 | MANAGER |
| 10 | PRESIDENT |
| 20 | ANALYST |
| 20 | CLERK |
| 20 | MANAGER |
| 30 | CLERK |
| 30 | MANAGER |
| 30 | SALESMAN |
±-------±----------+

案例:统计岗位的数量?

mysql> select count(distinct job) from emp;**
±--------------------+
| count(distinct job) |
±--------------------+
| 5 |
±--------------------+
1 row in set (0.00 sec)

连接查询

什么是连接查询?

在实际开发中,大部分的情况下都不是从单表中查询数据,一般都是多张表联合查询取出最终的结果。
 在实际开发中,一般一个业务都会对应多张表,比如:学生和班级,起码两张表。
 在实际上数据会存在大量的重复,导致数据的冗余。

连接查询的分类

根据语法出现的年代来划分的,包括:

SQL 92(一些老的DBA可能还在使用这种语法。DBA:Database Administrator)
SQL 99(比较新的语法)

根据表的连接方式来划分,包括:

  • 内连接:
    等值连接
    非等值连接
    自连接
  • 外连接:
    左外连接(左连接)
    右外连接(右连接)
  • 全连接(很少用)

在表的连接查询方面有一种现象被称为:笛卡尔积现象

案例:找出每一个员工的部门名称,要求显示员工名和部门名

mysql> select ename,deptno from emp;
±-------±-------+
| ename | deptno |
±-------±-------+
| SMITH | 20 |
| ALLEN | 30 |
| WARD | 30 |
| JONES | 20 |
| MARTIN | 30 |
| BLAKE | 30 |
| CLARK | 10 |
| SCOTT | 20 |
| KING | 10 |
| TURNER | 30 |
| ADAMS | 20 |
| JAMES | 30 |
| FORD | 20 |
| MILLER | 10 |
±-------±-------+

mysql> select * from dept
-> ;
±-------±-----------±---------+
| DEPTNO | DNAME | LOC |
±-------±-----------±---------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |

select ename,dname from emp,dept;

mysql> select ename,dname from emp,dept;//ename和dname要联合起来一块显示,黏到一块。
±-------±-----------+
| ename | dname |
±-------±-----------+
| SMITH | ACCOUNTING |
| SMITH | RESEARCH |
| SMITH | SALES |
| SMITH | OPERATIONS |
| ALLEN | ACCOUNTING |
| ALLEN | RESEARCH |
| ALLEN | SALES |
| ALLEN | OPERATIONS |
| WARD | ACCOUNTING |
| WARD | RESEARCH |
| WARD | SALES |
| WARD | OPERATIONS |
| JONES | ACCOUNTING |
| JONES | RESEARCH |
| JONES | SALES |
| JONES | OPERATIONS |
| MARTIN | ACCOUNTING |
| MARTIN | RESEARCH |
| MARTIN | SALES |
| MARTIN | OPERATIONS |
| BLAKE | ACCOUNTING |
| BLAKE | RESEARCH |
| BLAKE | SALES |
| BLAKE | OPERATIONS |
| CLARK | ACCOUNTING |
| CLARK | RESEARCH |
| CLARK | SALES |
| CLARK | OPERATIONS |
| SCOTT | ACCOUNTING |
| SCOTT | RESEARCH |
| SCOTT | SALES |
| SCOTT | OPERATIONS |
| KING | ACCOUNTING |
| KING | RESEARCH |
| KING | SALES |
| KING | OPERATIONS |
| TURNER | ACCOUNTING |
| TURNER | RESEARCH |
| TURNER | SALES |
| TURNER | OPERATIONS |
| ADAMS | ACCOUNTING |
| ADAMS | RESEARCH |
| ADAMS | SALES |
| ADAMS | OPERATIONS |
| JAMES | ACCOUNTING |
| JAMES | RESEARCH |
| JAMES | SALES |
| JAMES | OPERATIONS |
| FORD | ACCOUNTING |
| FORD | RESEARCH |
| FORD | SALES |
| FORD | OPERATIONS |
| MILLER | ACCOUNTING |
| MILLER | RESEARCH |
| MILLER | SALES |
| MILLER | OPERATIONS |
±-------±-----------+
56 rows in set (0.00 sec)

笛卡尔积现象:当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数两张表记录条数的乘积。

关于表的别名:

select e.ename, d.dname from emp e, dept d;

表的别名有什么好处

第一:执行效率高
 第二:可读性好

怎么避免笛卡尔积现象?

思考:避免了笛卡尔积现象,会减少记录的匹配次数吗?

不会,次数还是56此。只不过显示的是有效记录

案例:找出每一个员工的部门名称,要求显示员工名和部门名。

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)

内连接之等值连接

特点:条件是等量关系

案例:查询每个员工的部门名称,要求显示员工名和部门名

SQL92:(太老,不用了)
select e.ename, d.dname from emp e, dept d where e.deptno = d.deptno;

SQL99:(常用的)
select
e.ename, d.dname
from
emp e
join
dept d
**on **
e.deptno = d.deptno; //等值连接

select
e.ename, d.dname
from
emp e
inner join // inner可省略
dept d
**on **
e.deptno = d.deptno; //等值连接

SQL99语法结构更清晰一些:表的连接条件和后来的where条件分离了

内连接之非等值连接

最大的特点是:连接条件中的关系是非等量关系。

案例:找出每个员工的工资等级,要求显示员工名、工资、工资等级。
select
e.ename, e.sal, s.grade
from
emp e
join salgrade s
on
e.sal>=losal and e.sal<=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.00 sec)

内连接之自连接

最大的特点:一张表看做两张表。自己连接自己。

案例:找出每个员工的上级领导,要求显示员工名和对应的领导名。

select
a.ename, b.ename
from
emp a
inner join
emp b
on
a.mgr=b.deptno;

外连接

什么是外连接,和内连接有什么区别?
  内连接:假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来,这就是内连接。
AB两张表没有主副之分,两张表是平等的。

外连接:假设A和B表进行连接,使用外连接的话,AB两张表中有一张表是主表,一张表是副表,主要查询主表中的数据,捎带着查询副表,当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。

外连接的分类?

左外连接(左连接):表示左边的这张表是主表。
右外连接(右连接):表示右边的这张表是主表。

左连接有有连接的写法,右连接也会有对应左连接的写法

案例:找出每个员工的上级领导?(所有员工必须全部查询出来)

//inner可以省略

内连接
select a.ename, b.ename from emp a inner join emp b on a.mgr=b.empno;

//outer可以省略

外连接(左连接)
select a.ename, b.ename from emp a left outer join emp b on a.mgr=b.empno;

外连接(右连接)

select a.ename, b.ename from emp b right outer join emp a on a.mgr=b.empno;

外连接重要的特点是:主表的数据无条件的全部查询出来

案例:找出那个部门没有员工?

mysql> select d. from emp e right join dept d on e.deptno=d.deptno where e.empno is null;*
±-------±-----------±-------+
| DEPTNO | DNAME | LOC |
±-------±-----------±-------+
| 40 | OPERATIONS | BOSTON |
±-------±-----------±-------+
1 row in set (0.00 sec)

三张表怎么连接查询?

案例:找出每一个员工的部门名称以及工资等级

//全部员工
select * from emp;
//部门名称
select e.ename, d.dname from emp e join dept d on e.deptno=d.deptno;
//工资等级
select e.ename, s.grade from emp e join salgrade s on e.sal between losal and hisal;
//最终结合
select e.ename, d.dname, s.grade from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between losal and hisal;

案例:找出每个员工的部门名称、工资等级、以及上级领导。

select e.ename, d.dname, s.grade,b.ename from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between losal and hisal join emp b on e.mgr=b.empno;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤桜懶契

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值