1 #06章 多表查询
2
3 /*
4 SELECT....,....,....,
5 FROM....
6 WHERE...AND / OR /NOT ...
7 ORDER BY ..... (ASC/DESC),...,....
8 LIMIT....,.....
9 */
10
11
12 DESC employees
13
14 DESC departments
15
16 DESC locations
17
18 #查询员工名为‘Abel’的人在哪个城市工作
19 SELECT *
20 FROM employees
21 WHERE last_name = 'Abel'
22
23 SELECT *
24 FROM departments·
25 WHERE department_id = 80
26
27
28
29 SELECT *
30 FROM locations
31 WHERE location_id = '2500'
32
33
34 #2 . 出现笛卡尔积(或交叉连接)的错误
35 # 错误的原因:缺少了多表的连接条件
36
37 #错误的实现方式:每个员工都和每个部门匹配了一遍出现了错误
38
39 SELECT employee_id, department_name
40 FROM employees,departments; #查询出2889条记录
41
42
43 SELECT *
44 FROM employees #107 条记录
45
46
47
48 #错误的实现方式:
49 SELECT employee_id, department_name
50 FROM employees CROSS JOIN departments;
51
52
53 #3.多表查询的正确方式,需要有连接条件
54
55 SELECT employee_id, department_name
56 FROM employees,departments
57 #两个表的连接条件
58 WHERE employees.`department_id` = departments.`department_id`;
59
60
61 #4.如果查询语句中出现了多个表都存在的字段,则必须指明此字段所在的表
62
63 SELECT employees.employee_id, departments.department_name ,employees.department_id
64 FROM employees,departments
65 WHERE employees.`department_id` = departments.`department_id`;
66
67 #建议:从sql优化的角度,建议多表查询时候,每个字段前都指明其所在的表
68
69 #5.可以给表其别名,在SELECT 和WHERE中使用表的别名
70
71 SELECT t1.employee_id, t2.department_name ,t1.department_id
72 FROM employees t1,departments t2
73 WHERE t1.`department_id` = t2.`department_id`;
74
75
76 # 6.如果有n个表实现多表查询,则至少需要n-1个连接条件
77 #练习查询 员工employee_id, last_name ,department_name, city
78
79 SELECT t1.employee_id, t1.last_name, t2.department_name, t3.city
80 FROM employees t1 , departments t2, locations t3
81 WHERE t1.`department_id` = t2.`department_id`
82 AND t2.`location_id` = t3.`location_id`
83
84
85 /*
86 演绎式:提出问题1 -----> 解决问题1 ------> 提出问题2 -----> 解决问题2
87
88 归纳式:总 -- 分
89
90 */
91
92
93
94
95 #7.多表查询的分类
96
97 /*
98 角度1 : 等值连接 vs 非等值连接
99
100 角度2: 自连接 vs 非自连接
101
102 角度3: 内连接 vs 外连接
103
104
105
106
107 */
108
109
110 # 7.1 等值连接 vs 非等值连接
111
112 #非等值连接的例子: 员工工资等级,在区间内进行划分
113
114 SELECT *
115 FROM job_grades;
116
117
118 SELECT t1.last_name ,t1.salary , t2.grade_level
119 FROM employees t1, job_grades t2
120 #WHERE t1.`salary` BETWEEN t2.`lowest_sal` AND t2.`highest_sal`
121 WHERE t1.`salary` >= t2.`lowest_sal` AND t1.`salary`<= t2.`highest_sal`
122 ORDER BY grade_level ASC
123
124
125
126
127
128 # 7.1 自连接 vs 非自连接
129
130 SELECT *FROM employees;
131
132 #自连接例子
133 #练习:查询员工id, 员工姓名及管理这id和姓名,在同一张表下查询
134
135 SELECT t1.employee_id , t1.last_name , t2.employee_id , t2.last_name
136 FROM employees t1 ,employees t2
137 WHERE t1.`manager_id` = t2.`employee_id`
138
139
140
141
142
143 #7.3内连接 和 外连接
144
145 #内连接: 合并具有同一列的两个以上表的行, 结构集中不包含一个表与另一个表不匹配的行
146
147 SELECT employee_id, department_name
148 FROM employees t1,departments t2
149 WHERE t1.`department_id` = t2.`department_id`;
150
151 # 外连接: 合并具有同一列的两个以上表的行, 结构集中除了包含一个表与另一个表不匹配的行之外
152 # 还查询到了 左表 或 右表中不匹配的行
153
154 #外连接的分类:左外连接、右外连接、满外连接
155
156 # 左外连接: 两个表在连接过程中, 除了返回满足连接条件的行以外还返回左表中不满足条件的行, 这种连接称为左外连接
157 # 右外连接: 两个表在连接过程中, 除了返回满足连接条件的行以外还返回右表中不满足条件的行, 这种连接称为右外连接
158
159 # 查询所有员工的last_name, department_name信息 (查所有的信息,是外连接!!!)
160
161 SELECT employee_id, department_name
162 FROM employees t1,departments t2
163 WHERE t1.`department_id` = t2.`department_id`;
164
165 #SQL 92语法实现内连接: 见上, 略
166 #SQL 92语法实现外连接 : 使用 + ---------MYSQL 不支持SQL 92语法中外连接的写法 oracle支持!
167
168 SELECT employee_id, department_name
169 FROM employees t1,departments t2
170 WHERE t1.`department_id` = t2.`department_id`(+);
171
172
173 #SQL99语法中使用JOIN ... ON 的方式实现多表查询, 这种方式也能解决外连接的问题, mysql是支持这中方式的
174 #SQL99语法如何实现多表查询的
175
176
177 #SQL99语法如何实现内连接
178 SELECT employee_id, department_name
179 FROM employees t1 JOIN departments t2
180 ON t1.`department_id` = t2.`department_id`;
181
182 #SQL 92 语法实现内连接
183
184 SELECT t1.employee_id, t1.last_name, t2.department_name, t3.city
185 FROM employees t1 , departments t2, locations t3
186 WHERE t1.`department_id` = t2.`department_id`
187 AND t2.`location_id` = t3.`location_id`
188
189
190 SELECT * FROM locations
191
192
193 #SQL 99 语法实现内连接
194
195 SELECT last_name, department_name,city
196 FROM employees e JOIN departments d
197 ON e.`department_id` = d.`department_id`
198 JOIN locations l
199 ON d.`location_id` = l.`location_id`;
200
201
202 #SQL 99 语法实现外连接
203 #查询所有员工的last_name, department_name信息 (查所有的信息,是外连接!!!)
204
205 #右外连接:
206 SELECT last_name, department_name
207 FROM employees e RIGHT OUTER JOIN departments d
208 ON e.`department_id` = d.`department_id`
209
210 #左外连接:
211 SELECT last_name, department_name
212 FROM employees e LEFT OUTER JOIN departments d
213 ON e.`department_id` = d.`department_id`
214
215
216 #满外连接:MYSQL 不支持 FULL OUTER JOIN
217 SELECT last_name, department_name
218 FROM employees e FULL OUTER JOIN departments d
219 ON e.`department_id` = d.`department_id`;