Repository navigation
Expand file tree
/
Copy path[尚硅谷例题]_sql_quertion.txt
More file actions
553 lines (348 loc) · 14.3 KB
/
Copy path[尚硅谷例题]_sql_quertion.txt
File metadata and controls
553 lines (348 loc) · 14.3 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
【尚硅谷 www.atguigu.com】
/*************************************************************************************************/
第 1 章
/*************************************************************************************************/
1. 对于日期型数据, 做 *, / 运算不合法
2. 包含空值的数学表达式的值都为空值
3. 别名使用双引号!
4. oracle 中连接字符串使用 "||", 而不是 java 中的 "+"
5. 日期和字符只能在单引号中出现. 输出 last_name`s email is email
select last_name || ' `s email is ' || email
from employees
6. distinct 关键字, 以下语法错误
select last_name, distinct department_id
from employees
/*************************************************************************************************/
第 2 章
/*************************************************************************************************/
7. WHERE 子句紧随 FROM 子句
8. 查询 last_name 为 'King' 的员工信息
错误1: King 没有加上 单引号
select first_name, last_name
from employees
where last_name = King
错误2: 在单引号中的值区分大小写
select first_name, last_name
from employees
where last_name = 'king'
正确
select first_name, last_name
from employees
where last_name = 'King'
9. 查询 1998-4-24 来公司的员工有哪些?
注意: 日期必须要放在单引号中, 且必须是指定的格式
select last_name, hire_date
from employees
where hire_date = '24-APR -98'
10. 查询工资在 5000 -- 10000 之间的员工信息.
1). 使用 AND
2). 使用 BETWEEN .. AND .., 注意: 包含边界!!
11. 查询工资等于 6000, 7000, 8000, 9000, 10000 的员工信息
1). 使用 OR
2). 使用 IN
12. 查询 LAST_NAME 中有 'o' 字符的所有员工信息.
13. 查询 LAST_NAME 中第二个字符是 'o' 的所有员工信息.
14. 查询 LAST_NAME 中含有 '_' 字符的所有员工信息
1). 准备工作:
update employees
set last_name = 'Jones_Tom'
where employee_id = 195
2). 使用 escape 说明转义字符.
15. 查询 COMMISSION_PCT 字段为空的所有员工信息
16. 查询 COMMISSION_PCT 字段不为空的所有员工信息
17. ORDER BY:
1). 若查询中有表达式运算, 一般使用别名排序
2). 按多个列排序: 先按第一列排序, 若第一列中有相同的, 再按第二列排序.
/*************************************************************************************************/
第 3 章
/*************************************************************************************************/
18. 打印出 "2009年10月14日 9:25:40" 格式的当前系统的日期和时间.
注意: 使用双引号向日期中添加字符
19. 格式化数字: 1234567.89 为 1,234,567.89
20. 字符串转为数字时
1). 若字符串中没有特殊字符, 可以进行隐式转换:
select '1234567.89' + 100
from dual
2). 若字符串中有特殊字符, 例如 '1,234,567.89', 则无法进行隐式转换, 需要使用 to_number() 来完成
select to_number('1,234,567.89', '999,999,999.99') + 100
from dual
21. 对于把日期作为查询条件的查询, 一般都使用 to_date() 把一个字符串转为日期, 这样可以不必关注日期格式
select last_name, hire_date
from employees
where hire_date = to_date('1998-5-23', 'yyyy-mm-dd')
22. 转换函数: to_char(), to_number(), to_date()
23. 查询每个月倒数第 2 天入职的员工的信息.
select last_name, hire_date
from employees
where hire_date = last_day(hire_date) - 1
24. 计算公司员工的年薪
--错误写法: 因为空值计算的结果还是空值
select last_name, salary * 12 * (1 + commission_pct) year_sal
from employees
--正确写法
select last_name, salary * 12 * (1 + nvl(commission_pct, 0)) year_sal
from employees
25. 查询部门号为 10, 20, 30 的员工信息, 若部门号为 10, 则打印其工资的 1.1 倍, 20 号部门, 则打印其工资的 1.2 倍, 30 号部门打印其工资的 1.3 倍数
--使用 case-when-then-else-end
select last_name, department_id, salary, case department_id when 10 then salary * 1.1
when 20 then salary * 1.2
when 30 then salary * 1.3
end new_sal
from employees
where department_id in (10, 20, 30)
--使用 decode
select last_name, department_id, salary, decode(department_id, 10, salary * 1.1,
20, salary * 1.2,
30, salary * 1.3
) new_sal
from employees
where department_id in (10, 20, 30)
/*************************************************************************************************/
第 4 章
/*************************************************************************************************/
26. 多表连接查询时, 若两个表有同名的列, 必须使用表的别名对列名进行引用, 否则出错!
27. 查询出公司员工的 last_name, department_name, city
select last_name, department_name, city
from departments d, employees e, locations l
where d.department_id = e.department_id and d.location_id = l.location_id
28. 查询出 last_name 为 'Chen' 的 manager 的信息. (员工的 manager_id 是某员工的 employee_id)
0). 例如: 老张的员工号为: "1001", 我的员工号为: "1002",
我的 manager_id 为 "1001" --- 我的 manager 是"老张"
1). 通过两条 sql 查询:
select manager_id
from employees
where lower(last_name) = 'chen' --返回的结果为 108
select *
from employees
where employee_id = 108
2). 通过一条 sql 查询(自连接):
select m.*
from employees e, employees m
where e.manager_id = m.employee_id and e.last_name = 'Chen'
3). 通过一条 sql 查询(子查询):
select *
from employees
where employee_id = (
select manager_id
from employees
where last_name = 'Chen'
)
29. 查询每个员工的 last_name 和 GRADE_LEVEL(在 JOB_GRADES 表中). ---- 非等值连接
select last_name, salary, grade_level, lowest_sal, highest_sal
from employees e, job_grades j
where e.salary >= j.lowest_sal and e.salary <= j.highest_sal
30. 左外连接和右外连接
select last_name, e.department_id, department_name
from employees e, departments d
where e.department_id = d.department_id(+)
select last_name, d.department_id, department_name
from employees e, departments d
where e.department_id(+) = d.department_id
理解 "(+)" 的位置: 以左外连接为例, 因为左表需要返回更多的记录,
右表就需要 "加上" 更多的记录, 所以在右表的链接条件上加上 "(+)"
注意: 1). 两边都加上 "(+)" 符号, 会发生语法错误!
2). 这种语法为 Oracle 所独有, 不能在其它数据库中使用.
31. SQL 99 链接 Employees 表和 Departments 表
1).
select *
from employees join departments
using(department_id)
缺点: 要求两个表中必须有一样的列名.
2).
select *
from employees e join departments d
on e.department_id = d.department_id
3).多表链接
select e.last_name, d.department_name, l.city
from employees e join departments d
on e.department_id = d.department_id
join locations l
on d.location_id = l.location_id
32. SQL 99 的左外连接, 右外连接, 满外连接
1).
select last_name, department_name
from employees e left join departments d
on e.department_id = d.department_id
2).
select last_name, department_name
from employees e right join departments d
on e.department_id = d.department_id
3).
select last_name, department_name
from employees e full join departments d
on e.department_id = d.department_id
/*************************************************************************************************/
第 5 章
/*************************************************************************************************/
33. 查询 employees 表中有多少个部门
34. 查询全公司奖金基数的平均值(没有奖金的人按 0 计算)
35. 查询各个部门的平均工资
--错误: avg(salary) 返回公司平均工资, 只有一个值; 而 department_id 有多个值, 无法匹配返回
select department_id, avg(salary)
from employees
**在 SELECT 列表中所有未包含在组函数中的列都应该包含在 GROUP BY 子句中
--正确: 按 department_id 进行分组
select department_id, avg(salary)
from employees
group by department_id
36. Toronto 这个城市的员工的平均工资
37. (有员工的城市)各个城市的平均工资
38. 查询平均工资高于 8000 的部门 id 和它的平均工资.
39. 查询平均工资高于 6000 的 job_title 有哪些
/*************************************************************************************************/
第 6 章
/*************************************************************************************************/
40. 谁的工资比 Abel 高?
1). 写两条 SQL 语句.
SELECT salary
FROM employees
WHERE last_name = 'Abel'
--返回值为 11000
SELECT last_name, salary
FROM employees
WHERE salary > 11000
2). 使用子查询 -- 一条 SQL 语句
SELECT last_name, salary
FROM employees
WHERE salary > (
SELECT salary
FROM employees
WHERE last_name = 'Abel'
)
41. 子查询注意:
1). 子查询要包含在括号内
2). 将子查询放在比较条件的右侧
42. 查询工资最低的员工信息: last_name, salary
43. 查询平均工资最低的部门信息
--查询平均工资最低的部门信息和该部门的平均工资
44. 查询平均工资最高的 job 信息
45. 查询平均工资高于公司平均工资的部门有哪些?
46. 查询出公司中所有 manager 的详细信息.
47. 各个部门中 最高工资中最低的那个部门的 最低工资是多少
48. 查询平均工资最高的部门的 manager 的详细信息: last_name, department_id, email, salary
49. 查询 1999 年来公司的人所有员工的最高工资的那个员工的信息.
50. 多行子查询的 any 和 all
select department_id
from employees
group by department_id
having avg(salary) >= any(
--所有部门的平均工资
select avg(salary)
from employees
group by department_id
)
any 和任意一个值比较, 所以其条件最为宽松, 所以实际上只需和平均工资最低的比较, 返回所有值
而 all 是和全部的值比较, 条件最为苛刻, 所以实际上返回的只需和平均工资最高的比较, 所以返回平均工资最高的 department_id
/*************************************************************************************************/
第 7 章
/*************************************************************************************************/
51. 利用子查询创建表 myemp, 该表中包含 employees 表的 employee_id(id), last_name(name), salary(sal), email 字段
52. 对现有的表进行修改操作
1). 添加一个新列
ALTER TABLE myemp ADD(age number(3))
2). 修改现有列的类型
ALTER TABLE myemp MODIFY(name varchar2(30));
3). 修改现有列的名字
ALTER TABLE myemp RENAME COLUMN sal TO salary;
4). 删除现有的列
ALTER TABLE myemp DROP COLUMN age;
53. 清空表(截断: truncate), 不能回滚!!
54.
1). 创建一个表, 该表和 employees 有相同的表结构, 但为空表: create table emp2 as select * from employees where 1 = 2;
2). 把 employees 表中 80 号部门的所有数据复制到 emp2 表中:
insert into emp2 select * from employees where department_id = 80;
/*************************************************************************************************/
第 8 章
/*************************************************************************************************/
55. 更改 108 员工的信息: 使其工资变为所在部门中的最高工资, job 变为公司中平均工资最低的 job
56. 删除 108 号员工所在部门中工资最低的那个员工.
/*************************************************************************************************/
第 9 章
/*************************************************************************************************/
57. 定义非空约束
1). 非空约束只能定义在列级.
2). 不指定约束名
create table emp2 (name varchar2(30) not null, age number(3));
3). 指定约束名
create table emp3(name varchar2(30) constraint name_not_null not null, age number(3));
58. 唯一约束
1). 行级定义
①. 不指定约束名
create table emp2 (name varchar2(30) unique, age number(3));
②. 指定约束名
create table emp3 (name varchar2(30) constraint name_uq unique, age number(3));
2). 表级定义: 必须指定约束名
①. 指定约束名
create table emp3 (name varchar2(30), age number(3), constraint name_uq unique(name));
58.1 主键约束:
59. 外键约束
1). 行级定义
①. 不指定约束名
create table emp2(
emp_id number(6),
name varchar2(25),
dept_id number(4) references dept2(dept_id))
②. 指定约束名
create table emp3(
emp_id number(6),
name varchar2(25),
dept_id number(4) constraint dept_fk3 references dept2(dept_id))
2). 表级定义: 必须指定约束名
①. 指定约束名
create table emp4(
emp_id number(6),
name varchar2(25),
dept_id number(4),
constraint dept_fk2 foreign key(dept_id) references dept2(dept_id))
60. 约束需要注意的地方
1). ** 非空约束只能定义在列级
2). ** 唯一约束的列值可以为空
3). ** 外键引用的列起码要有一个唯一约束
61. 建立外键约束时的级联删除问题:
1). 级联删除:
create table emp2(
id number(3) primary key,
name varchar2(25) unique,
dept_id references dept2(dept_id) on delete cascade)
2). 级联置空
create table emp3(
id number(3) primary key,
name varchar2(25) unique,
dept_id references dept2(dept_id) on delete set null)
62. 查询员工表中 salary 前 10 的员工信息.
select last_name, salary
from (select last_name, salary from employees order by salary desc)
where rownum <= 10
说明: rownum "伪列" ---- 数据表本身并没有这样的列, 是 oracle 数据库为每个数据表 "加上的" 列. 可以标识行号.
默认情况下 rownum 按主索引来排序. 若没有主索引则自然排序.
注意: **对 ROWNUM 只能使用 < 或 <=, 而是用 =, >, >= 都将不能返回任何数据.
63. 查询员工表中 salary 10 - 20 的员工信息.
select *
from(
select rownum rn, temp.*
from (
select last_name, salary
from employees e
order by salary desc
) temp
)
where rn > 10 and rn < 21
64. 对 oralce 数据库中记录进行分页: 每页显示 10 条记录, 查询第 5 页的数据
select employee_id, last_name, salary
from (
select rownum rn, employee_id, last_name, salary
from employees
) e
where e.rn <= 50 and e.rn > 40
注意: **对 oracle 分页必须使用 rownum "伪列"!
select employee_id, last_name, salary
from (
select rownum rn, employee_id, last_name, salary
from employees
) e
where e.rn <= pageNo * pageSize and e.rn > (pageNo - 1) * pageSize
65. 创建序列:
1). create sequence hs increment by 10 start with 10
2). NEXTVAL 应在 CURRVAL 之前指定 ,二者应同时有效
65. 序列通常用来生成主键:
INSERT INTO emp2 VALUES (emp2_seq.nextval, 'xx', ...)