Mysql笔记:第03章_基本的SELECT语句

第03章_基本的SELECT语句

1. SQL概述

1.1 SQL背景知识
  • 1946年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖。在这几十年里,无数的技术、产业在这片江湖里沉浮,有的方兴未艾,有的已经几幕兴衰。但在这片浩荡的波动里,有一门技术从未消失,甚至“老当益壮”,那就是SQL。
  • 45 年前,也就是 1974 年,IBM研究员发布了一篇揭开数据库技术的论文《SEQUEL:一门结构化的英语查询语言》,直到今天这门结构化的查询语言并没有太大的变化,相比于其他语言,SQL 的半衰期可以说是非常长 了。
  • 不论是前端工程师,还是后端算法工程师,都一定会和数据打交道,都需要了解如何又快又准确地提取自己想要的数据。更别提数据分析师了,他们的工作就是和数据打交道,整理不同的报告,以便指导业务决策。
  • SQL(Structured Query Language,结构化查询语言)是使用关系模型的数据库应用语言, 与数据直接打交道 ,由IBM 上世纪70年代开发出来。后由美国国家标准局(ANSI)开始着手制定SQL标准,先后有 SQL-86 , SQL-89 ,SQL-92 , SQL-99 等标准。
  • SQL 有两个重要的标准,分别是 SQL92 和 SQL99,它们分别代表了 92 年和 99 年颁布的 SQL 标准,我们今天使用的SQL 语言依然遵循这些标准。
  • 不同的数据库生产厂商都支持SQL语句,但都有特有内容。
    请添加图片描述
  • 自从 SQL 加入了 TIOBE 编程语言排行榜,就一直保持在 Top 10。
1.3 SQL 分类

SQL语言在功能上主要分为如下3大类:
DDL(Data Definition Languages、数据定义语言),这些语句定义了不同的数据库、表、视图、索引等数据库对象,还可以用来创建、删除、修改数据库和数据表的结构。
主要的语句关键字包括 CREATE 、 DROP 、 ALTER 等。
DML(Data Manipulation Language、数据操作语言),用于添加、删除、更新数据库记录,并检查数据完整性。主要的语句关键字包括 INSERT 、 DELETE 、 UPDATE 等。

DQL(数据查询语言) 则是用来查询数据的,主要是 SELECT 语句。SELECT是SQL语言的基础,最为重要。

DCL(Data Control Language、数据控制语言),用于定义数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括 GRANT 、 REVOKE 、 COMMIT、ROLLBACK 、 SAVEPOINT 等。

因为查询语句使用的非常的频繁,所以很多人把查询语句单拎出来一类:DQL(数据查询语言)。还有单独将 COMMIT 、 ROLLBACK 取出来称为TCL (Transaction Control Language,事务控制语言)。

SQL 语句的分类:

  • DDL 数据定义语言
  • DML 数据操作语言
  • DQL 数据查询语言:select
  • DCL 数据控制语言

2. SQL语言的规则与规范

2.1SQL语言的规则
  • SQL 可以写在一行或者多行。为了提高可读性,各子句分行写,必要时使用缩进
  • 每条命令以 ; 或 \g 或 \G 结束
  • 关键字不能被缩写也不能分行
  • 关于标点符号
    1.必须保证所有的()、单引号、双引号是成对结束的
    2.必须使用英文状态下的半角输入方式
    3.字符串型和日期时间类型的数据可以使用单引号(’ ‘)表示
    4.列的别名,尽量使用双引号(” “),而且不建议省略as
2.2 SQL大小写规范 (建议遵守)
  • MySQL 在 Windows 环境下是大小写不敏感的
  • MySQL 在 Linux 环境下是大小写敏感的
    1.数据库名、表名、表的别名、变量名是严格区分大小写的
    2.关键字、函数名、列名(或字段名)、列的别名(字段的别名) 是忽略大小写的。
  • 推荐采用统一的书写规范:
    1.数据库名、表名、表别名、字段名、字段别名等都小写
    2.SQL 关键字、函数名、绑定变量等都大写
2.3 注 释

可以使用如下格式的注释结构

1
2
3
单行注释:#注释文字(MySQL特有的方式)
单行注释:-- 注释文字(--后面必须包含一个空格。)
多行注释:/* 注释文字 */
2.4 命名规则(暂时了解)
  • 数据库、表名不得超过30个字符,变量名限制为29个
  • 必须只能包含 A–Z, a–z, 0–9, _共63个字符
  • 数据库名、表名、字段名等对象名中间不要包含空格
  • 同一个MySQL软件中,数据库不能同名;同一个库中,表不能重名;同一个表中,字段不能重名
  • 必须保证你的字段没有和保留字、数据库系统或常用方法冲突。如果坚持使用,请在SQL语句中使用`(着重号)引起来
  • 保持字段名和类型的一致性,在命名字段并为其指定数据类型的时候一定要保证一致性。假如数据类型在一个表里是整数,那在另一个表里可就别变成字符型了

举例:

1
2
3
4
5
6
7
8
9
10
11
#以下两句是一样的,不区分大小写
show databases;
SHOW DATABASES;
#创建表格
#create table student info(...); #表名错误,因为表名有空格
create table student_info(...);
#其中order使用``飘号,因为order和系统关键字或系统函数名等预定义标识符重名了
CREATE TABLE `order`();
select id as "编号", `name` as "姓名" from t_stu; #起别名时,as都可以省略
select id as 编号, `name` as 姓名 from t_stu; #如果字段别名中没有空格,那么可以省略""
select id as 编 号, `name` as 姓 名 from t_stu; #错误,如果字段别名中有空格,那么不能省略""
2.5 数据导入指令

在命令行客户端登录mysql,使用source指令导入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mysql> source d:\mysqldb.sql
1
mysql> desc employees;
/*输出
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| employee_id | int | NO | PRI | 0 | |
| first_name | varchar(20) | YES | | NULL | |
| last_name | varchar(25) | NO | | NULL | |
| email | varchar(25) | NO | UNI | NULL | |
| phone_number | varchar(20) | YES | | NULL | |
| hire_date | date | NO | | NULL | |
| job_id | varchar(10) | NO | MUL | NULL | |
| salary | double(8,2) | YES | | NULL | |
| commission_pct | double(2,2) | YES | | NULL | |
| manager_id | int | YES | MUL | NULL | |
| department_id | int | YES | MUL | NULL | |
+----------------+-------------+------+-----+---------+-------+
*/

3. 基本的SELECT语句

3.0 SELECT…
1
2
SELECT 1; #没有任何子句
SELECT 9/2; #没有任何子句
3.1 SELECT … FROM

语法:

1
2
SELECT 标识选择哪些列
FROM 标识从哪个表中选择

选择全部列:

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT *
FROM departments;
/*部分输出
+---------------+----------------------+------------+-------------+
| department_id | department_name | manager_id | location_id |
+---------------+----------------------+------------+-------------+
| 10 | Administration | 200 | 1700 |
| 20 | Marketing | 201 | 1800 |
| 30 | Purchasing | 114 | 1700 |
| 40 | Human Resources | 203 | 2400 |
| 50 | Shipping | 121 | 1500 |
| 60 | IT | 103 | 1400 |
*/

一般情况下,除非需要使用表中所有的字段数据,最好不要使用通配符‘*’。使用通配符虽然可以节省输入查询语句的时间,但是获取不需要的列数据通常会降低查询和所使用的应用程序的效率。通配符的优势是,当不知道所需要的列的名称时,可以通过它获取它们。
在生产环境下,不推荐你直接使用 SELECT * 进行查询。

选择特定的列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SELECT department_id, location_id
FROM departments;
/*
部分输出
+---------------+-------------+
| department_id | location_id |
+---------------+-------------+
| 60 | 1400 |
| 50 | 1500 |
| 10 | 1700 |
| 30 | 1700 |
| 90 | 1700 |
| 100 | 1700 |
| 110 | 1700 |
| 120 | 1700 |
| 130 | 1700 |
*/

请添加图片描述

MySQL中的SQL语句是不区分大小写的,因此SELECT和select的作用是相同的,但是,许多开发人员习惯将关键字大写、数据列和表名小写,读者也应该养成一个良好的编程习惯,这样写出来的代码更容易阅读和维护。

3.2 列的别名
  • 重命名一个列
  • 便于计算
  • 紧跟列名,也可以在列名和别名之间加入关键字AS,别名使用双引号,以便在别名中包含空格或特殊的字符并区分大小写。
  • AS 可以省略
  • 建议别名简短,见名知意
  • 举例
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
SELECT last_name AS name, commission_pct comm
FROM employees;
/*部分输出
+-------------+------+
| name | comm |
+-------------+------+
| King | NULL |
| Kochhar | NULL |
| De Haan | NULL |
| Hunold | NULL |
| Ernst | NULL |
| Austin | NULL |
*/

select * from employees;
/*部分输出
+-------------+-------------+-------------+----------+--------------------+------------+------------+----------+----------------+------------+---------------+
| employee_id | first_name | last_name | email | phone_number | hire_date | job_id | salary | commission_pct | manager_id | department_id |
+-------------+-------------+-------------+----------+--------------------+------------+------------+----------+----------------+------------+---------------+
| 100 | Steven | King | SKING | 515.123.4567 | 1987-06-17 | AD_PRES | 24000.00 | NULL | NULL | 90 |
| 101 | Neena | Kochhar | NKOCHHAR | 515.123.4568 | 1989-09-21 | AD_VP | 17000.00 | NULL | 100 | 90 |
| 102 | Lex | De Haan | LDEHAAN | 515.123.4569 | 1993-01-13 | AD_VP | 17000.00 | NULL | 100 | 90 |
| 103 | Alexander | Hunold | AHUNOLD | 590.423.4567 | 1990-01-03 | IT_PROG | 9000.00 | NULL | 102 | 60 |
| 104 | Bruce | Ernst | BERNST | 590.423.4568 | 1991-05-21 | IT_PROG | 6000.00 | NULL | 103 | 60 |
| 105 | David | Austin | DAUSTIN | 590.423.4569 | 1997-06-25 | IT_
*/

select employee_id,last_name,department_id from employees;
/*部分输出:
+-------------+-------------+---------------+
| employee_id | last_name | department_id |
+-------------+-------------+---------------+
| 100 | King | 90 |
| 101 | Kochhar | 90 |
| 102 | De Haan | 90 |
| 103 | Hunold | 60 |
| 104 | Ernst | 60 |
| 105 | Austin | 60 |
| 106 | Pataballa | 60 |
| 107 | Lorentz | 60 |
| 108 | Greenberg | 100 |
| 109 | Faviet | 100 |
*/
#列的别名:
select employee_id id ,last_name l_nm ,department_id AS dept_id from employees;
/*部分输出
+-----+-------------+---------+
| id | l_nm | dept_id |
+-----+-------------+---------+
| 100 | King | 90 |
| 101 | Kochhar | 90 |
| 102 | De Haan | 90 |
| 103 | Hunold | 60 |
| 104 | Ernst | 60 |
| 105 | Austin | 60 |
*/
#列的别名:
SELECT last_name "Name", salary*12 "Annual Salary"FROM employees;
/*部分输出:
+-------------+---------------+
| Name | Annual Salary |
+-------------+---------------+
| King | 288000.00 |
| Kochhar | 204000.00 |
| De Haan | 204000.00 |
| Hunold | 108000.00 |
| Ernst | 72000.00 |
| Austin | 57600.00 |
| Pataballa | 57600.00 |
| Lorentz | 50400.00 |
*/

3.3 去除重复行

默认情况下,查询会返回全部行,包括重复行。

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
SELECT department_id
FROM employees;
/*部分输出
+---------------+
| department_id |
+---------------+
| NULL |
| 10 |
| 20 |
| 20 |
| 30 |
| 30 |
| 30 |
| 30 |
| 30 |
*/

**SELECT语句中使用关键字DISTINCT去除重复行**
SELECT DISTINCT department_id
FROM employees;
/*输出
+---------------+
| department_id |
+---------------+
| NULL |
| 10 |
| 20 |
| 30 |
| 40 |
| 50 |
| 60 |
| 70 |
| 80 |
| 90 |
| 100 |
| 110 |
+---------------+
*/

针对于:

1
2
SELECT DISTINCT department_id,salary
FROM employees;

这里有两点需要注意:

  1. DISTINCT 需要放到所有列名的前面,如果写成 SELECT salary, DISTINCT department_id FROM employees 会报错。
  2. DISTINCT 其实是对后面所有列名的组合进行去重,你能看到最后的结果是 74 条,因为这 74 个部门id不同,都有 salary 这个属性值。如果你想要看都有哪些不同的部门(department_id),只需要写 DISTINCT department_id 即可,后面不需要再加其他的列名了。
3.4 空值参与运算

所有运算符或列值遇到null值,运算的结果都为null

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT employee_id,salary,commission_pct,
12 * salary * (1 + commission_pct) "annual_sal"
FROM employees;
/*部分输出
+-------------+----------+----------------+------------+
| employee_id | salary | commission_pct | annual_sal |
+-------------+----------+----------------+------------+
| 100 | 24000.00 | NULL | NULL |
| 101 | 17000.00 | NULL | NULL |
| 102 | 17000.00 | NULL | NULL |
| 103 | 9000.00 | NULL | NULL |
| 104 | 6000.00 | NULL | NULL |
| 105 | 4800.00 | NULL | NULL |
| 106 | 4800.00 | NULL | NULL |
| 107 | 4200.00 | NULL | NULL |
*/

这里一定要注意,在 MySQL 里面, 空值不等于空字符串。一个空字符串的长度是 0,而一个空值的长度是空。而且,在 MySQL 里面,空值是占用空间的。null不等同于0、’ ’ 以及’null’.

3.5 着重号

错误的:

1
2
3
4
5
mysql> SELECT * FROM ORDER;
/*报错
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'ORDER' at line 1
*/

正确的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SELECT * FROM `ORDER`;
/*输出
+----------+------------+
| order_id | order_name |
+----------+------------+
| 1 | shkstart |
| 2 | tomcat |
| 3 | dubbo |
+----------+------------+
*/
mysql> SELECT * FROM `order`;
/*输出:
+----------+------------+
| order_id | order_name |
+----------+------------+
| 1 | shkstart |
| 2 | tomcat |
| 3 | dubbo |
+----------+------------+
*/

结论:
要保证表中的字段、表名等没有和保留字、数据库系统或常用方法冲突。如果真的相同,请在SQL语句中使用一对``(着重号)引起来。

3.6 查询常数

SELECT 查询还可以对常数进行查询。对的,就是在 SELECT 查询结果中增加一列固定的常数列。这列的取值是我们指定的,而不是从数据表中动态取出的。
你可能会问为什么我们还要对常数进行查询呢?
SQL 中的 SELECT 语法的确提供了这个功能,一般来说我们只从一个表中查询数据,通常不需要增加一个固定的常数列,但如果我们想整合不同的数据源,用常数列作为这个表的标记,就需要查询常数。比如说,我们想对 employees 数据表中的员工姓名进行查询,同时增加一列字段 corporation ,这个字段固定值为“尚硅谷”,可以这样写:

1
SELECT '尚硅谷' as corporation, last_name FROM employees;
3.7 过滤数据

使用 WHERE 字句,将不满足条件的行过滤掉,WHERE 子句紧随 FROM 子句,过滤条件声明在 FROM 结构的后面。

语法:

1
2
3
SELECT 字段1, 字段2, ...
FROM 表名
WHERE 过滤条件;

查询90号部门的员工信息:

1
2
3
SELECT *
FROM employees
WHERE department_id=90;

在这里插入图片描述

查询 last_name 为 ‘King’ 的员工信息:

1
2
3
SELECT *
FROM employees
WHERE last_name='King';

在这里插入图片描述

1
2
3
SELECT *
FROM employees
WHERE last_name='king';

该语句的查询结果与上面相同
原因:在 windows 环境下,对大小写不敏感导致 MySQL 中对大小写也不敏感,但是由于 MySQL 的不严谨导致字符串中的大小写也不进行区分,所以上面的两句结果相同。
在其他数据中不会出现这种情况。

在这里插入图片描述

在 windows 环境下不区分大小,指的是字段名,表名,关键字,不包括引号内的字符串。

4. 显示表结构

使用DESCRIBE 或 DESC 命令,表示表结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DESCRIBE employees;

DESC employees;

mysql> desc employees;
/*部分输出
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| employee_id | int(6) | NO | PRI | 0 | |
| first_name | varchar(20) | YES | | NULL | |
| last_name | varchar(25) | NO | | NULL | |
| email | varchar(25) | NO | UNI | NULL | |
| phone_number | varchar(20) | YES | | NULL | |
| hire_date | date | NO | | NULL | |
| job_id | varchar(10) | NO | MUL | NULL | |
| salary | double(8,2) | YES | | NULL | |
| commission_pct | double(2,2) | YES | | NULL | |
| manager_id | int(6) | YES | MUL | NULL | |
| department_id | int(4) | YES | MUL | NULL | |
+----------------+-------------+------+-----+---------+-------+
11 rows in set (0.00 sec)
*/

其中,各个字段的含义分别解释如下:
Field:表示字段名称。
Type:表示字段类型,这里 barcode、goodsname 是文本型的,price 是整数类型的。
Null:表示该列是否可以存储NULL值。
Key:表示该列是否已编制索引。PRI表示该列是表主键的一部分;UNI表示该列是UNIQUE索引的一部分;MUL表示在列中某个给定值允许出现多次。
Default:表示该列是否有默认值,如果有,那么值是多少。
Extra:表示可以获取的与给定列有关的附加信息,例如AUTO_INCREMENT等。

背景:
请添加图片描述
语法:

1
2
3
SELECT 字段1,字段2
FROM 表名
WHERE 过滤条件

使用WHERE 子句,将不满足条件的行过滤掉WHERE子句紧随 FROM子句

举例:

1
2
3
4
5
6
7
8
9
10
select employee_id, last_name, job_id, department_id  from employees where department_id=90;
/*输出:
+-------------+-----------+---------+---------------+
| employee_id | last_name | job_id | department_id |
+-------------+-----------+---------+---------------+
| 100 | King | AD_PRES | 90 |
| 101 | Kochhar | AD_VP | 90 |
| 102 | De Haan | AD_VP | 90 |
+-------------+-----------+---------+---------------+
*/

5.讲课代码

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
#第03章_基本的SELECT语句

#1. SQL的分类
/*
DDL:数据定义语言。CREATE \ ALTER \ DROP \ RENAME \ TRUNCATE


DML:数据操作语言(增删改查)。INSERT \ DELETE \ UPDATE \ SELECT (重中之重)


DCL:数据控制语言。COMMIT \ ROLLBACK \ SAVEPOINT \ GRANT \ REVOKE

学习技巧:大处着眼、小处着手。

*/

/*
2.1 SQL的规则 ----必须要遵守
- SQL 可以写在一行或者多行。为了提高可读性,各子句分行写,必要时使用缩进
- 每条命令以 ; 或 \g 或 \G 结束
- 关键字不能被缩写也不能分行
- 关于标点符号
- 必须保证所有的()、单引号、双引号是成对结束的
- 必须使用英文状态下的半角输入方式
- 字符串型和日期时间类型的数据可以使用单引号(' ')表示
- 列的别名,尽量使用双引号(" "),而且不建议省略as

2.2 SQL的规范 ----建议遵守
- MySQL 在 Windows 环境下是大小写不敏感的
- MySQL 在 Linux 环境下是大小写敏感的
- 数据库名、表名、表的别名、变量名是严格区分大小写的
- 关键字、函数名、列名(或字段名)、列的别名(字段的别名) 是忽略大小写的。
- 推荐采用统一的书写规范:
- 数据库名、表名、表别名、字段名、字段别名等都小写
- SQL 关键字、函数名、绑定变量等都大写


3. MySQL的三种注释的方式

*/

USE dbtest2;

-- 这是一个查询语句
SELECT * FROM emp;

INSERT INTO emp
VALUES(1002,'Tom'); #字符串、日期时间类型的变量需要使用一对''表示

INSERT INTO emp
VALUES(1003,'Jerry');

# SELECT * FROM emp\G

SHOW CREATE TABLE emp\g

/*
4. 导入现有的数据表、表的数据。
方式1:source 文件的全路径名
举例:source d:\atguigudb.sql;


方式2:基于具体的图形化界面的工具可以导入数据
比如:SQLyog中 选择 “工具” -- “执行sql脚本” -- 选中xxx.sql即可。
*/

#5. 最基本的SELECT语句: SELECT 字段1,字段2,... FROM 表名
SELECT 1 + 1,3 * 2;

SELECT 1 + 1,3 * 2
FROM DUAL; #dual:伪表

# *:表中的所有的字段(或列)
SELECT * FROM employees;

SELECT employee_id,last_name,salary
FROM employees;


#6. 列的别名
# as:全称:alias(别名),可以省略
# 列的别名可以使用一对""引起来,不要使用''
SELECT employee_id emp_id,last_name AS lname,department_id "部门id",salary * 12 AS "annual sal"
FROM employees;

# 7. 去除重复行
#查询员工表中一共有哪些部门id呢?

#错误的:没有去重的情况
SELECT department_id
FROM employees;
/*部分输出(1.有null值,一些员工没有部门2.部门有重复的)
+---------------+
| department_id |
+---------------+
| NULL |
| 10 |
| 20 |
| 20 |
| 30 |
| 30 |
| 30 |
| 30 |
| 30 |
*/


#正确的:去重的情况
SELECT DISTINCT department_id
FROM employees;
/*全部输出(部门没有重复的)
+---------------+
| department_id |
+---------------+
| NULL |
| 10 |
| 20 |
| 30 |
| 40 |
| 50 |
| 60 |
| 70 |
| 80 |
| 90 |
| 100 |
| 110 |
+---------------+
*/

#错误的(报错):
SELECT salary,DISTINCT department_id
FROM employees;



#仅仅是没有报错,但是没有实际意义。
#不符合实际需求
SELECT DISTINCT department_id,salary
FROM employees;
/*部分输出(DISTINCT为部门、薪水都去重)
+---------------+----------+
| department_id | salary |
+---------------+----------+
| 90 | 24000.00 |
| 90 | 17000.00 |
| 60 | 9000.00 |
| 60 | 6000.00 |
| 60 | 4800.00 |
| 60 | 4200.00 |
| 100 | 12000.00 |
*/

#8. 空值参与运算
# 1. 空值:null
# 2. null不等同于0'''null'
SELECT * FROM employees;



#3. 空值参与运算:结果一定也为空。
SELECT employee_id,salary "月工资",salary * (1 + commission_pct) * 12 "年工资",commission_pct
FROM employees;
/*部分输出(年工资出错变成null)
+-------------+-----------+-----------+----------------+
| employee_id | 月工资 | 年工资 | commission_pct |
+-------------+-----------+-----------+----------------+
| 100 | 24000.00 | NULL | NULL |
| 101 | 17000.00 | NULL | NULL |
| 102 | 17000.00 | NULL | NULL |
| 103 | 9000.00 | NULL | NULL |
| 104 | 6000.00 | NULL | NULL |
| 105 | 4800.00 | NULL | NULL |
| 106 | 4800.00 | NULL | NULL |
| 107 | 4200.00 | NULL | NULL |
*/


#实际问题的解决方案:引入IFNULL
SELECT employee_id,salary "月工资",salary * (1 + IFNULL(commission_pct,0)) * 12 "年工资",commission_pct
FROM `employees`;
#IFNULL(commission_pct,0)-->commission_pct字段为null时
#用0替换,否则采用原数值
/*部分输出(正确)
+-------------+-----------+-----------+----------------+
| employee_id | 月工资 | 年工资 | commission_pct |
+-------------+-----------+-----------+----------------+
| 100 | 24000.00 | 288000.00 | NULL |
| 101 | 17000.00 | 204000.00 | NULL |
| 102 | 17000.00 | 204000.00 | NULL |
| 103 | 9000.00 | 108000.00 | NULL |
| 104 | 6000.00 | 72000.00 | NULL |
| 105 | 4800.00 | 57600.00 | NULL |
| 106 | 4800.00 | 57600.00 | NULL |
| 107 | 4200.00 | 50400.00 | NULL |
| 108 | 12000.00 | 144000.00 | NULL |
| 109 | 9000.00 | 108000.00 | NULL |
| 110 | 8200.00 | 98400.00 | NULL |
*/

#9. 着重号 ``
#ORDER是一个保留字
#如果查询的表名和关键字、保留字冲突就要使用着重号
SELECT * FROM `order`;

#10. 查询常数
#-->若查询内容都和一个常数有关(如都是尚硅谷的员工)
#且常数和表中属性无关,就可以使用查询常数
SELECT '尚硅谷',123,employee_id,last_name
FROM employees;
/*部分输出:
+-----------+-----+-------------+-------------+
| 尚硅谷 | 123 | employee_id | last_name |
+-----------+-----+-------------+-------------+
| 尚硅谷 | 123 | 100 | King |
| 尚硅谷 | 123 | 101 | Kochhar |
| 尚硅谷 | 123 | 102 | De Haan |
| 尚硅谷 | 123 | 103 | Hunold |
| 尚硅谷 | 123 | 104 | Ernst |
| 尚硅谷 | 123 | 105 | Austin |
| 尚硅谷 | 123 | 106 | Pataballa |
*/

#11.显示表结构

DESCRIBE employees; #显示了表中字段的详细信息
/*输出:
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| employee_id | int(6) | NO | PRI | 0 | |
| first_name | varchar(20) | YES | | NULL | |
| last_name | varchar(25) | NO | | NULL | |
| email | varchar(25) | NO | UNI | NULL | |
| phone_number | varchar(20) | YES | | NULL | |
| hire_date | date | NO | | NULL | |
| job_id | varchar(10) | NO | MUL | NULL | |
| salary | double(8,2) | YES | | NULL | |
| commission_pct | double(2,2) | YES | | NULL | |
| manager_id | int(6) | YES | MUL | NULL | |
| department_id | int(4) | YES | MUL | NULL | |
+----------------+-------------+------+-----+---------+-------+
*/

DESC employees;#效果和语句DESCRIBE employees;一样

DESC departments;
/*输出:
+-----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+-------+
| department_id | int(4) | NO | PRI | 0 | |
| department_name | varchar(30) | NO | | NULL | |
| manager_id | int(6) | YES | MUL | NULL | |
| location_id | int(4) | YES | MUL | NULL | |
+-----------------+-------------+------+-----+---------+-------+
*/

#12.过滤数据

#练习:查询90号部门的员工信息
SELECT * FROM employees
#过滤条件,声明在FROM结构的后面
WHERE department_id = 90;
/*输出:
+-------------+------------+-----------+----------+--------------+------------+---------+----------+----------------+------------+---------------+
| employee_id | first_name | last_name | email | phone_number | hire_date | job_id | salary | commission_pct | manager_id | department_id |
+-------------+------------+-----------+----------+--------------+------------+---------+----------+----------------+------------+---------------+
| 100 | Steven | King | SKING | 515.123.4567 | 1987-06-17 | AD_PRES | 24000.00 | NULL | NULL | 90 |
| 101 | Neena | Kochhar | NKOCHHAR | 515.123.4568 | 1989-09-21 | AD_VP | 17000.00 | NULL | 100 | 90 |
| 102 | Lex | De Haan | LDEHAAN | 515.123.4569 | 1993-01-13 | AD_VP | 17000.00 | NULL | 100 | 90 |
+-------------+------------+-----------+----------+--------------+------------+---------+----
*/

#练习:查询last_name为'King'的员工信息
SELECT *
FROM EMPLOYEES
WHERE LAST_NAME = 'King';
/*输出:
+-------------+------------+-----------+-------+--------------------+------------+---------+----------+----------------+------------+---------------+
| employee_id | first_name | last_name | email | phone_number | hire_date | job_id | salary | commission_pct | manager_id | department_id |
+-------------+------------+-----------+-------+--------------------+------------+---------+----------+----------------+------------+---------------+
| 100 | Steven | King | SKING | 515.123.4567 | 1987-06-17 | AD_PRES | 24000.00 | NULL | NULL | 90 |
| 156 | Janette | King | JKING | 011.44.1345.429268 | 1996-01-30 | SA_REP | 10000.00 | 0.35 | 146 | 80 |
+-------------+------------+-----------+-------+---
*/

6.课后练习

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
#第03章_基本的SELECT语句的课后练习

# 1.查询员工12个月的工资总和,并起别名为ANNUAL SALARY
#理解1:计算12月的基本工资
SELECT employee_id,last_name,salary * 12 "ANNUAL SALARY"
FROM employees;
/*部分输出:
+-------------+-------------+---------------+
| employee_id | last_name | ANNUAL SALARY |
+-------------+-------------+---------------+
| 100 | King | 288000.00 |
| 101 | Kochhar | 204000.00 |
| 102 | De Haan | 204000.00 |
| 103 | Hunold | 108000.00 |
| 104 | Ernst | 72000.00 |
| 105 | Austin | 57600.00 |
| 106 | Pataballa | 57600.00 |
*/

#理解2:计算12月的基本工资和奖金
SELECT employee_id,last_name,salary * 12 * (1 + IFNULL(commission_pct,0)) "ANNUAL SALARY"
FROM employees;
/*部分输出:
+-------------+-------------+---------------+
| employee_id | last_name | ANNUAL SALARY |
+-------------+-------------+---------------+
| 100 | King | 288000.00 |
| 101 | Kochhar | 204000.00 |
| 102 | De Haan | 204000.00 |
| 103 | Hunold | 108000.00 |
| 104 | Ernst | 72000.00 |
| 105 | Austin | 57600.00 |
| 106 | Pataballa | 57600.00 |
| 107 | Lorentz | 50400.00 |
| 108 | Greenberg | 144000.00 |

*/


# 2.查询employees表中去除重复的job_id以后的数据
SELECT DISTINCT job_id
FROM employees;
/*部分输出:
+------------+
| job_id |
+------------+
| AC_ACCOUNT |
| AC_MGR |
| AD_ASST |
| AD_PRES |
| AD_VP |
| FI_ACCOUNT |
| FI_MGR
*/


# 3.查询工资大于12000的员工姓名和工资
SELECT last_name,salary
FROM employees
WHERE salary > 12000;
/*输出:
+-----------+----------+
| last_name | salary |
+-----------+----------+
| King | 24000.00 |
| Kochhar | 17000.00 |
| De Haan | 17000.00 |
| Russell | 14000.00 |
| Partners | 13500.00 |
| Hartstein | 13000.00 |
+-----------+----------+
*/



# 4.查询员工号为176的员工的姓名和部门号
SELECT last_name,department_id
FROM employees
WHERE employee_id = 176;
/*输出:
+-----------+---------------+
| last_name | department_id |
+-----------+---------------+
| Taylor | 80 |
+-----------+---------------+
*/



# 5.显示表 departments 的结构,并查询其中的全部数据
DESCRIBE departments;
/*输出:
+-----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+-------+
| department_id | int(4) | NO | PRI | 0 | |
| department_name | varchar(30) | NO | | NULL | |
| manager_id | int(6) | YES | MUL | NULL | |
| location_id | int(4) | YES | MUL | NULL | |
+-----------------+-------------+------+-----+---------+-------+
*/

SELECT * FROM departments;
/*部分输出:
+---------------+----------------------+------------+-------------+
| department_id | department_name | manager_id | location_id |
+---------------+----------------------+------------+-------------+
| 10 | Administration | 200 | 1700 |
| 20 | Marketing | 201 | 1800 |
| 30 | Purchasing | 114 | 1700 |
| 40 | Human Resources | 203 | 2400 |
| 50 | Shipping | 121 | 1500 |
*/