文章目录

  • 1. 什么是连接查询?
  • 2. 连接查询的分类
  • 3. 笛卡尔积现象(笛卡尔乘积现象)
  • 4. 表的别名
  • 5. 怎么避免笛卡尔积现象?


1. 什么是连接查询?

在实际开发中,大部分情况下都不是从单表中查询数据,一般都是多张表联合查询出最终结果。

在实际的开发中,一般一个业务都会对应多张表,比如:学生和班级,起码两张表。

当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。连接操作给用户带来很大的灵活性,他们可以在任何时候增加新的数据类型。为不同实体创建新的表,然后通过连接进行查询。

stuno		stuname			classno		classname
-----------------------------------------------------------------------------------
1			zs					1				北京大兴区亦庄经济技术开发区第二中学高三1班
2			ls					1				北京大兴区亦庄经济技术开发区第二中学高三1班
...

学生和班级信息存储到一张表中,结果就像上面一样,数据会存在大量的重复,导致数据的冗余,浪费存储空间!

2. 连接查询的分类

根据语法出现的年代来划分的话可以分为:

SQL92(一些老的DBA可能还在使用这种语法。DBA:DataBase Adminstrator,数据集管理员);
SQL99(比较新的语法);

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

(1)内连接:

  • 等值连接
  • 非等值连接
  • 自连接

(2)外连接

  • 左外连接(左连接)
  • 右外连接(右连接)

(3)全连接(这个很少用)

3. 笛卡尔积现象(笛卡尔乘积现象)

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

表A和B连接查询时,表A中一条记录都与表B中的所有记录进行匹配

我们可以通过一个案例来引出这个现象。

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

select * from emp;

我们可以看到这张emp表记录了员工的姓名(ename)和部门编号(deptno),但是没有部门的名称;

+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME  | JOB       | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
|  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800.00 |    NULL |     20 |
|  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
|  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
|  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
|  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
|  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
|  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
|  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
|  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 |    NULL |     10 |
|  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 |    0.00 |     30 |
|  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100.00 |    NULL |     20 |
|  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950.00 |    NULL |     30 |
|  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
|  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.01 sec)

但我们发现,部门名称在dept表中

select * from dept;
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
4 rows in set (0.00 sec)

因此,要完成案例中要求,需要在在emp中取出员工名字,在dept表中取出部门名字。

select ename, dname from emp,dept; // ename和dname要联合在一块显示,粘到一块。

这条查询语句将会产生56条记录,因为emp中每一员工信息(14)都会与dept中记录(4条)进行匹配,这将产生14 x 4 = 56条记录。

查询结果:以下查询结果手动省略。

+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | ACCOUNTING |
| SMITH  | RESEARCH   |
| SMITH  | SALES      |
| SMITH  | OPERATIONS |
 .....................    
| MILLER | ACCOUNTING |
| MILLER | RESEARCH   |
| MILLER | SALES      |
| MILLER | OPERATIONS |
+--------+------------+
56 rows in set (0.00 sec)

4. 表的别名

在写sql语句时,我们可以对表进行起别名,如上面sql语句,我们可以写成:

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

使用别名的优势:

第一: 执行效率高; 以上sql语句为了,如果不使用别名,查询enme字段,它先会去emp找,再去dept表中找。
有时候,两张表中可能会存在字段名一样的情况。

第二:可读性好;

5. 怎么避免笛卡尔积现象?

当然是加条件进行过滤。

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

答案是:不会。 以以上查询案例为例,查询次数还是56次。只不过显示的是有效记录。

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

为了避免笛卡尔乘积,我们需要判断两个部门的编号是否一致,如果一致则匹配。正确的写法为:

select e.ename, d.dname from emp e,dept d where e.deptno = d.deptno; // SQL92的老语法
+--------+------------+
| 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.01 sec)