[TOC]
一。关键字
distinct
作用:查询结果去重
位置:查询字段的前方,出现两个字段之前,表示两个字段联合查询。
—-> 统计岗位数量1
2
3
4
5
6
7
8
9
10
11
12
13
14
15mysql> select count(job) from emp;
+------------+
| count(job) |
+------------+
| 14 |
+------------+
1 row in set (0.01 sec)
mysql> select count(distinct job) from emp;
+---------------------+
| count(distinct job) |
+---------------------+
| 5 |
+---------------------+
1 row in set (0.00 sec)
一、什么是连接查询
二、 连接查询的分类
根据表连接的方式分类
内连接 —–> 值一一对应
- 等值连接
- 非等值连接
- 自连接
外连接
==哪个==外连接,表示 ==把哪张表当成主表==- 左外连接(也叫左连接) —>左表为主表
- 右外连接(也叫右连接) —>右表为主表
什么时候使用 内 外连接
- 判断两张表是否有 ==主次之分==
全连接 (不常用)
- a 和 b 两张都是主表,
三、SQL92语法
四、案例分析
内连接: 完全能够匹配上这个条件的数据查询出来。( A 和 B 进行连接,A B 没有主次之分 )
A 内连接之等值连接
笛卡尔积现象
笛卡尔积现象:当两张表进行连接查询,没有任何条件限制的时候,最终查询结果的条数,是两张表条数的乘积,这种现象被称为:笛卡尔积现象。(笛卡尔发现的,这是一个属性现象)
1
2
3
4
5
6
7
8
9
10
11 mysql> select dname,ename from emp,dept;
+------------+--------+
| dname | ename |
+------------+--------+
| OPERATIONS | SMITH |
………………………………………………
| ACCOUNTING | MILLER |
+------------+--------+
56 rows in set (0.01 sec)
=14*4
避免该现象:加筛选条件
查询每个员工所在部门名称,显示员工名和部门名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# SQL92写法
mysql>
select
ename,dname
#这样子写查询效率会偏低,mysql会 分别去 emp 和 dept 两张表中都去查询这两个字段
#提高效率
# emp.ename,dept.dname;
from
emp,dept
# 起别名
# emp xx, dept xxx
where
emp.deptno=dept.deptno; and xxx加其他条件
SQL92的缺点:结构不清晰,表的链接条件,和后期进一步筛选的条件,都放到了 where 后面。
+--------+------------+
| 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的语法
mysql>
select
ename,dname
#这样子写查询效率会偏低,mysql会 分别去 emp 和 dept 两张表中都去查询这两个字段
#提高效率
# emp.ename,dept.dname;
from
emp
inner join
#inner 可省略
dept
# 起别名
# emp xx, dept xxx
on
emp.deptno=dept.deptno;
where
xx
SQL92优点:表连接的条件是独立的,连接之后如果需要进一步筛选,再往后添加where即可。
+--------+------------+
| 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)Q:dept中有4条记录,empt中有14条。最终查询的结果条数是14条,但是匹配的过程中,匹配的次数减少了吗?
A:并没有,还是56次(每次匹配时,都会拿empt中的一条数据去逐一匹配dept中的4条记录。只不过进行了四选一(选符合条件的那条)_)
B 内连接之非等值连接 ——> 条件不是一个等量关系
- 找出每个员工的薪资登记,要求显示员工名、薪资、薪资登记?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32mysql>
select
e.ename,e.sal,s.grade
from
emp e
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.00 sec)
C、内连接之自连接 ——>
技巧:一张表看做两张表
- 查询员工的上级领导(mgr),要求显示员工名和对应的领导名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94select empno,ename,mgr from emp;
+-------+--------+------+
| empno | ename | mgr |
+-------+--------+------+
| 7369 | SMITH | 7902 |
| 7499 | ALLEN | 7698 |
| 7521 | WARD | 7698 |
| 7566 | JONES | 7839 |
| 7654 | MARTIN | 7698 |
| 7698 | BLAKE | 7839 |
| 7782 | CLARK | 7839 |
| 7788 | SCOTT | 7566 |
| 7839 | KING | NULL |
| 7844 | TURNER | 7698 |
| 7876 | ADAMS | 7788 |
| 7900 | JAMES | 7698 |
| 7902 | FORD | 7566 |
| 7934 | MILLER | 7782 |
+-------+--------+------+
14 rows in set (0.00 sec)
用 mgr 的序号,去匹配 empno 得到ename ,然后填入
-->技巧,看成两张表
emp a 员工表
+-------+--------+------+
| empno | ename | mgr |
+-------+--------+------+
| 7369 | SMITH | 7902 |
| 7499 | ALLEN | 7698 |
| 7521 | WARD | 7698 |
| 7566 | JONES | 7839 |
| 7654 | MARTIN | 7698 |
| 7698 | BLAKE | 7839 |
| 7782 | CLARK | 7839 |
| 7788 | SCOTT | 7566 |
| 7839 | KING | NULL |
| 7844 | TURNER | 7698 |
| 7876 | ADAMS | 7788 |
| 7900 | JAMES | 7698 |
| 7902 | FORD | 7566 |
| 7934 | MILLER | 7782 |
+-------+--------+------+
14 rows in set (0.00 sec)
emp b领导表
+-------+--------+------+
| empno | ename | mgr |
+-------+--------+------+
| 7369 | SMITH | 7902 |
| 7499 | ALLEN | 7698 |
| 7521 | WARD | 7698 |
| 7566 | JONES | 7839 |
| 7654 | MARTIN | 7698 |
| 7698 | BLAKE | 7839 |
| 7782 | CLARK | 7839 |
| 7788 | SCOTT | 7566 |
| 7839 | KING | NULL |
| 7844 | TURNER | 7698 |
| 7876 | ADAMS | 7788 |
| 7900 | JAMES | 7698 |
| 7902 | FORD | 7566 |
| 7934 | MILLER | 7782 |
+-------+--------+------+
14 rows in set (0.00 sec)
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.01 sec)
King没有领导。
外连接—-> 存 在 主表(即 主表中不匹配 其他表的项也会被列举出来。)
A.右外连接
使用 emp 表中的 deptno 对应 ,dept 表中的 deptno 字段,显示结果匹配的,ename 和 dname 字段,并把 dept 中不匹配的 dname 也全部显示出来
1 | mysql> select |
B. 左外连接
1 | mysql> |
任何一个右连接都有左连接的写法。
任何一个左连接都有右连接的写法。
Q:外连接的查询结果条数一定是 >= 内连接的查询结果条数?
A:正确**
外连接案例
- 查询每个员工的上级领导,要求显示所有员工的名字和领导名?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43mysql> select empno,ename,mgr from emp;
+-------+--------+------+
| empno | ename | mgr |
+-------+--------+------+
| 7369 | SMITH | 7902 |
| 7499 | ALLEN | 7698 |
| 7521 | WARD | 7698 |
| 7566 | JONES | 7839 |
| 7654 | MARTIN | 7698 |
| 7698 | BLAKE | 7839 |
| 7782 | CLARK | 7839 |
| 7788 | SCOTT | 7566 |
| 7839 | KING | NULL |
| 7844 | TURNER | 7698 |
| 7876 | ADAMS | 7788 |
| 7900 | JAMES | 7698 |
| 7902 | FORD | 7566 |
| 7934 | MILLER | 7782 |
+-------+--------+------+
14 rows in set (0.00 sec)
# 1.分析思路 ---> 一张表
# 2.判断主表 ---> a员工表
mysql> select a.ename as '员工名',b.ename from emp a left join emp b on a.mgr=b.empno;
+--------+-------+
| ename | ename |
+--------+-------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| KING | NULL |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
+--------+-------+
14 rows in set (0.00 sec)
五、多张表之间进行连接
1 | select |