第四章 操作数据表中的记录

这一章主要是记录的操作,之前已经学过记录的插入、查找、删除,下面进行更加详细的讲解。

1. 插入记录

1)第一种方法

INSERT [INTO] tbl_name [(col_name,…)] {VALUES|VALUE} ({expr | DEFAULT},…),(…),…
打开mysql服务器,连接客户端,使用test数据库:

1
2
3
4
5
6
C:\Windows\system32>net start mysql

C:\Windows\system32>mysql -uroot -p
Enter password: ****

mysql> USE test;

为节省空间这里只给出指令,没有运行结果。
下面来看一个test数据库里面都有哪些数据表啦,当然你的可能和我不太一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| provinces |
| tb1 |
| tb2 |
| tb3 |
| tb4 |
| tb5 |
| tb6 |
| users |
| users1 |
| users2 |
+----------------+
10 rows in set (0.04 sec)

可以看到上一个章节创建的数据表都还在。
如果存在users数据表的话,先把它删除,待会重新创建一下:

1
2
mysql> DROP TABLE users;
Query OK, 0 rows affected (0.00 sec)

重新创建users数据表:

1
2
3
4
5
6
7
8
mysql> CREATE TABLE users(
-> id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
-> username VARCHAR(20) NOT NULL,
-> password VARCHAR(32) NOT NULL,
-> age TINYINT UNSIGNED NOT NULL DEFAULT 10,
-> sex BOOLEAN
-> );
Query OK, 0 rows affected (0.04 sec)

在这就省略查看是否真正创建成功啦,自行查看。
接下来我们往表里插入几条记录:

1
2
3
4
5
6
7
8
9
10
mysql> INSERT users VALUES(NULL,'hua','123',18,true);
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM users;
+----+----------+----------+-----+------+
| id | username | password | age | sex |
+----+----------+----------+-----+------+
| 1 | hua | 123 | 18 | 1 |
+----+----------+----------+-----+------+
1 row in set (0.03 sec)

我们对id这个自增量赋值为NULL,其值为1。

1
2
3
4
5
6
7
8
9
10
11
mysql> INSERT users VALUES(NULL,'hao','123',18,true);
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM users;
+----+----------+----------+-----+------+
| id | username | password | age | sex |
+----+----------+----------+-----+------+
| 1 | hua | 123 | 18 | 1 |
| 2 | hao | 123 | 18 | 1 |
+----+----------+----------+-----+------+
2 rows in set (0.00 sec)

还有一种方式:

1
2
3
4
5
6
7
8
9
10
11
12
mysql> INSERT users VALUES(DEFAULT,'yue','123',18,true);
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM users;
+----+----------+----------+-----+------+
| id | username | password | age | sex |
+----+----------+----------+-----+------+
| 1 | hua | 123 | 18 | 1 |
| 2 | hao | 123 | 18 | 1 |
| 3 | yue | 123 | 18 | 1 |
+----+----------+----------+-----+------+
3 rows in set (0.00 sec)

以上说明:如果想对自动递增的字段赋值,可以输入NULL或者DEFAULT.
另外上面三个记录我们都对每个字段进行了赋值,如果缺少则会出现错误:

1
2
mysql> INSERT users VALUES(NULL,'chun','123',18);
ERROR 1136 (21S01): Column count doesn't match value count at row 1

说明如果省略列名的话,所有的列必须依次赋值。
除了可以书写确切的数字以外,还可以书写表达式:

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> INSERT users VALUES(DEFAULT,'yuan','123',20*2-20,true);
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM users;
+----+----------+----------+-----+------+
| id | username | password | age | sex |
+----+----------+----------+-----+------+
| 1 | hua | 123 | 18 | 1 |
| 2 | hao | 123 | 18 | 1 |
| 3 | yue | 123 | 18 | 1 |
| 4 | yuan | 123 | 20 | 1 |
+----+----------+----------+-----+------+
4 rows in set (0.00 sec)

说明对整型字段赋值,可以使用数学表达式。当然也可以是字符表达式,或者某个函数。
再来看下DEFAULT,除了可以对自动赋值的字段赋值,还可以对设置了默认约束的字段赋值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> INSERT users VALUES(DEFAULT,'yue','123',DEFAULT,true);
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM users;
+----+----------+----------+-----+------+
| id | username | password | age | sex |
+----+----------+----------+-----+------+
| 1 | hua | 123 | 18 | 1 |
| 2 | hao | 123 | 18 | 1 |
| 3 | yue | 123 | 18 | 1 |
| 4 | yuan | 123 | 20 | 1 |
| 5 | yue | 123 | 10 | 1 |
+----+----------+----------+-----+------+
5 rows in set (0.00 sec)

第五条记录的age被赋值为默认值10。
以上都是插入一条记录,下面如何一次性插入多条记录呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> INSERT users VALUES(DEFAULT,'ye','123',20*2-20,true),(DEFAULT,'chun',md5(123),DEFAULT,0);
Query OK, 2 rows affected (0.03 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> SELECT * FROM users;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 1 | hua | 123 | 18 | 1 |
| 2 | hao | 123 | 18 | 1 |
| 3 | yue | 123 | 18 | 1 |
| 4 | yuan | 123 | 20 | 1 |
| 5 | yue | 123 | 10 | 1 |
| 6 | ye | 123 | 20 | 1 |
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 10 | 0 |
+----+----------+----------------------------------+-----+------+
7 rows in set (0.00 sec)

md5(‘123’)表示计算字符串的哈希值

2)第二种方法

INSERT [INTO] tbl_name SET col_name={expr | DEFAULT},..
与第一种方式区别在于,此方法可以使用子查询(SubQuery) ,而且只能一次性插入一条记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> INSERT users SET username = 'tian',password = '1233';
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM users;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 1 | hua | 123 | 18 | 1 |
| 2 | hao | 123 | 18 | 1 |
| 3 | yue | 123 | 18 | 1 |
| 4 | yuan | 123 | 20 | 1 |
| 5 | yue | 123 | 10 | 1 |
| 6 | ye | 123 | 20 | 1 |
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 10 | 0 |
| 8 | tian | 1233 | 10 | NULL |
+----+----------+----------------------------------+-----+------+
8 rows in set (0.00 sec)

因为age有默认值,sex允许为空,所以可以只对username和password赋值。

3)第三种方法

INSERT SELECT语句:
INSERT [INTO] tbl_name [(col_name,….)] SELECT …
此方法可以将查询结果插入到指定数据表。
由于对于SELECT语句理解较少,暂时先放这。(本章第9小节进行了讲解)

2. 单表更新记录

当我们书写记录的过程中,字段值可能出现错误,或者说我们想要更改字段值,就需要使用UPDATE语句,下面这种方式是单表更新,还有一种方式是多表更新,这种方式等学到连接时再讲。

UPDATE [LOW_PRIORITY] [IGNORE] table_reference SET col_name1={expr|DEFAULT}[,col_name2={expr|DEFAULT}]…[WHERE where_condition]

如果省略WHERE条件,将对所有的记录更新。
下面来看一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql> UPDATE users SET age=age+10;
Query OK, 8 rows affected (0.00 sec)
Rows matched: 8 Changed: 8 Warnings: 0

mysql> SELECT * FROM users;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 1 | hua | 123 | 28 | 1 |
| 2 | hao | 123 | 28 | 1 |
| 3 | yue | 123 | 28 | 1 |
| 4 | yuan | 123 | 30 | 1 |
| 5 | yue | 123 | 20 | 1 |
| 6 | ye | 123 | 30 | 1 |
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 20 | 0 |
| 8 | tian | 1233 | 20 | NULL |
+----+----------+----------------------------------+-----+------+
8 rows in set (0.00 sec)

第一个语句的意思就是,将所有记录的age字段的值加10。
上面的例子是更新了一列,当然我也可以更新俩列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql> UPDATE users SET age=age-id,sex=0;
Query OK, 8 rows affected (0.03 sec)
Rows matched: 8 Changed: 8 Warnings: 0

mysql> SELECT * FROM users;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 1 | hua | 123 | 27 | 0 |
| 2 | hao | 123 | 26 | 0 |
| 3 | yue | 123 | 25 | 0 |
| 4 | yuan | 123 | 26 | 0 |
| 5 | yue | 123 | 15 | 0 |
| 6 | ye | 123 | 24 | 0 |
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 13 | 0 |
| 8 | tian | 1233 | 12 | 0 |
+----+----------+----------------------------------+-----+------+
8 rows in set (0.00 sec)

我更新age为age减去id的值,并且将sex全部设置为了0;
上面都是对全部的记录更新,下面就让我们使用WHERE对特定的记录进行更新吧!
将所有id为偶数的user的age加上10:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql> UPDATE users SET age=age+10 WHERE id%2=0;
Query OK, 4 rows affected (0.03 sec)
Rows matched: 4 Changed: 4 Warnings: 0

mysql> SELECT * FROM users;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 1 | hua | 123 | 27 | 0 |
| 2 | hao | 123 | 36 | 0 |
| 3 | yue | 123 | 25 | 0 |
| 4 | yuan | 123 | 36 | 0 |
| 5 | yue | 123 | 15 | 0 |
| 6 | ye | 123 | 34 | 0 |
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 13 | 0 |
| 8 | tian | 1233 | 22 | 0 |
+----+----------+----------------------------------+-----+------+
8 rows in set (0.00 sec)

可以看到有四条记录被修改。

3. 单表删除记录

如果数据表中的记录不想要啦,还可以进行删除操作,同样也有两种方式:单表删除和多表删除,也只看单表删除。

DELETE FROM tbl_name [WHERE where_condition]

当省略WHERE时将删除所有记录
下面我们删除id=5的记录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> DELETE FROM users WHERE id = 5;
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM users;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 1 | hua | 123 | 27 | 0 |
| 2 | hao | 123 | 36 | 0 |
| 3 | yue | 123 | 25 | 0 |
| 4 | yuan | 123 | 36 | 0 |
| 6 | ye | 123 | 34 | 0 |
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 13 | 0 |
| 8 | tian | 1233 | 22 | 0 |
+----+----------+----------------------------------+-----+------+
7 rows in set (0.00 sec)

那么当我们再增加一条记录时,它的id是5呢还是9呢?
试试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> INSERT users VALUES(NULL,'hui','345',18,0);
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM users;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 1 | hua | 123 | 27 | 0 |
| 2 | hao | 123 | 36 | 0 |
| 3 | yue | 123 | 25 | 0 |
| 4 | yuan | 123 | 36 | 0 |
| 6 | ye | 123 | 34 | 0 |
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 13 | 0 |
| 8 | tian | 1233 | 22 | 0 |
| 9 | hui | 345 | 18 | 0 |
+----+----------+----------------------------------+-----+------+
8 rows in set (0.00 sec)

答案是9。可见当增加记录时,即使前面id号不连续,它仍然为当前最大的id加一。

4. SELECT查询表达式解析

曾有人说过select语句占数据表操作的百分之八十以上,嗯。。。还没有体会到
select select_expr
[
from table_references 表的参照
[where where_condition] 条件
[group by {col_name|position} [asc|sesc],…记录的分组
[having where_condition] 分组时对分组的条件进行设定
[order by {col_name|expr|position} [asc|desc]…]对于结果进行排序
[limit {[offset,]row_count|row_count OFFSET offset}]限制返回结果的数量
]

(下面几节依次讲解)
每一个表达式表示想要的一列,必须有至少一个
多个列之间英文逗号分隔
星号()表示所有列。tbl_name.可以表示命名表的所有列

之前我们最常使用的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> SELECT * FROM users;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 1 | hua | 123 | 27 | 0 |
| 2 | hao | 123 | 36 | 0 |
| 3 | yue | 123 | 25 | 0 |
| 4 | yuan | 123 | 36 | 0 |
| 6 | ye | 123 | 34 | 0 |
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 13 | 0 |
| 8 | tian | 1233 | 22 | 0 |
| 9 | hui | 345 | 18 | 0 |
+----+----------+----------------------------------+-----+------+
8 rows in set (0.00 sec)

这是对所有列的查看,如果我只想看特定的几个列呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> SELECT id,username FROM users;
+----+----------+
| id | username |
+----+----------+
| 1 | hua |
| 2 | hao |
| 3 | yue |
| 4 | yuan |
| 6 | ye |
| 7 | chun |
| 8 | tian |
| 9 | hui |
+----+----------+
8 rows in set (0.00 sec)

只显示了id和username两个列,查询的顺序和数据表中列的顺序可以不一致,下面看看当我把id和username的查询顺序倒过来以后的情形:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> SELECT username,id FROM users;
+----------+----+
| username | id |
+----------+----+
| hua | 1 |
| hao | 2 |
| yue | 3 |
| yuan | 4 |
| ye | 6 |
| chun | 7 |
| tian | 8 |
| hui | 9 |
+----------+----+
8 rows in set (0.00 sec)

显示的结果也倒过来啦,根据select的顺序显示。
tbl_name.*可以表示命名表的所有列,也就是可以在列的前面加上数据表的名字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> SELECT users.username,users.id FROM users;
+----------+----+
| username | id |
+----------+----+
| hua | 1 |
| hao | 2 |
| yue | 3 |
| yuan | 4 |
| ye | 6 |
| chun | 7 |
| tian | 8 |
| hui | 9 |
+----------+----+
8 rows in set (0.00 sec)

和上面结果一样,当然,当我们只对一个表进行操作时,没有这个必要。在对多表进行操作时,可以清晰辨认列属于哪张数据表。
有些字段的名字比较复杂,不太容易记忆,这时可以赋予别名。
查询表达式可以使用[AS] alias_name为其赋予别名
别名可用于GROUP BY,ORDER BY或HAVING子句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> SELECT id AS username,username AS uname FROM users;
+----------+-------+
| username | uname |
+----------+-------+
| 1 | hua |
| 2 | hao |
| 3 | yue |
| 4 | yuan |
| 6 | ye |
| 7 | chun |
| 8 | tian |
| 9 | hui |
+----------+-------+
8 rows in set (0.00 sec)

将id命名为username,将username命名为uname。
AS可以省略,当然不推荐,有时可能与显示多条字段混淆。
5. where语句进行条件查询
对记录进行过滤,如果没有指定WHERE子句,则显示所有记录
在WHERE表达式中,可以使用MySQL支持的函数或运算符

6. 查询结果分组

[GROUP BY {col_name | position} [ASC | DESC], …]
ASC:升序,默认
DESC:降序
position:SELECT语句中列的序号

1
2
3
4
5
6
7
8
9
10
mysql> SELECT password FROM users GROUP BY password;
+----------------------------------+
| password |
+----------------------------------+
| 123 |
| 1233 |
| 202cb962ac59075b964b07152d234b70 |
| 345 |
+----------------------------------+
4 rows in set (0.00 sec)

根据password进行分组,分成了四个组
除了写名字还可以写位置:

1
2
3
4
5
6
7
8
9
10
mysql> SELECT password FROM users GROUP BY 1;
+----------------------------------+
| password |
+----------------------------------+
| 123 |
| 1233 |
| 202cb962ac59075b964b07152d234b70 |
| 345 |
+----------------------------------+
4 rows in set (0.00 sec)

这里1是指select字段中第一个出现的字段,这里明显是password ,所以尽量指定名称,直观一点
如果把sex放第一个位置,那么只有一个分组啦

1
2
3
4
5
6
7
mysql> SELECT sex,password FROM users GROUP BY 1;
+------+----------+
| sex | password |
+------+----------+
| 0 | 123 |
+------+----------+
1 row in set (0.00 sec)

7. 分组条件

[ HAVING where_condition ]
这时我们可以对符合一定条件的记录进行分组

1
2
mysql> SELECT password FROM users GROUP BY 1 HAVING age>10;
ERROR 1054 (42S22): Unknown column 'age' in 'having clause'

想对age>10的password进行分组,居然出现错误。
原因有两个:
第一个:HAVING 后面可以使用聚合函数(MAX最大值, MIN最小值,AVG平均值,SUM求和)
第二个:不使用聚合函数的话,HAVING 后出现的字段也必须在SELECT后面出现
来试一下:

1
2
3
4
5
6
7
8
9
10
mysql> SELECT password,age FROM users GROUP BY 1 HAVING age>10;
+----------------------------------+-----+
| password | age |
+----------------------------------+-----+
| 123 | 27 |
| 1233 | 22 |
| 202cb962ac59075b964b07152d234b70 | 13 |
| 345 | 18 |
+----------------------------------+-----+
4 rows in set (0.00 sec)

在SELECT后面加上age后,成功分类
再试一下聚合函数:

1
2
3
4
5
6
7
8
9
10
mysql> SELECT password FROM users GROUP BY 1 HAVING AVG(age)>10;
+----------------------------------+
| password |
+----------------------------------+
| 123 |
| 1233 |
| 202cb962ac59075b964b07152d234b70 |
| 345 |
+----------------------------------+
4 rows in set (0.00 sec)

8. 查询结果排序

除了可以对查询结果条件进行指定,还可以对查询结果进行排序
[ORDER BY { col_name | expr | position }[ ASC | DESC ], … ]
可以按照某一字段进行排序,也可以按照位置进行排序,和GROUP BY完全相同的,ASC为升序,并且是默认的,DESC为降序,也可以同时以两个或者两个以上字段进行排序。
将查询结果按id降序排列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> SELECT * FROM users ORDER BY id DESC;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 9 | hui | 345 | 18 | 0 |
| 8 | tian | 1233 | 22 | 0 |
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 13 | 0 |
| 6 | ye | 123 | 34 | 0 |
| 4 | yuan | 123 | 36 | 0 |
| 3 | yue | 123 | 25 | 0 |
| 2 | hao | 123 | 36 | 0 |
| 1 | hua | 123 | 27 | 0 |
+----+----------+----------------------------------+-----+------+
8 rows in set (0.00 sec)

当然,也可以对两个字段进行排序
先对age进行升序排列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> SELECT * FROM users ORDER BY age;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 13 | 0 |
| 9 | hui | 345 | 18 | 0 |
| 8 | tian | 1233 | 22 | 0 |
| 3 | yue | 123 | 25 | 0 |
| 1 | hua | 123 | 27 | 0 |
| 6 | ye | 123 | 34 | 0 |
| 2 | hao | 123 | 36 | 0 |
| 4 | yuan | 123 | 36 | 0 |
+----+----------+----------------------------------+-----+------+
8 rows in set (0.00 sec)

可以看到age有相同的,比如36,再按照id降序排列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> SELECT * FROM users ORDER BY age,id DESC;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 13 | 0 |
| 9 | hui | 345 | 18 | 0 |
| 8 | tian | 1233 | 22 | 0 |
| 3 | yue | 123 | 25 | 0 |
| 1 | hua | 123 | 27 | 0 |
| 6 | ye | 123 | 34 | 0 |
| 4 | yuan | 123 | 36 | 0 |
| 2 | hao | 123 | 36 | 0 |
+----+----------+----------------------------------+-----+------+
8 rows in set (0.00 sec)

可以看到最后两条age相同的记录,又按照id进行了降序排列。

9. 限制查询数量

1)限制查询结果返回的数量

[ LIMIT { [ offset, ] row_count OFFSET offset } ]
默认使用SELECT,返回所有的记录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> SELECT * FROM users;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 1 | hua | 123 | 27 | 0 |
| 2 | hao | 123 | 36 | 0 |
| 3 | yue | 123 | 25 | 0 |
| 4 | yuan | 123 | 36 | 0 |
| 6 | ye | 123 | 34 | 0 |
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 13 | 0 |
| 8 | tian | 1233 | 22 | 0 |
| 9 | hui | 345 | 18 | 0 |
+----+----------+----------------------------------+-----+------+
8 rows in set (0.00 sec)

使用limit语句就可以限制返回的数量:

1
2
3
4
5
6
7
8
mysql> SELECT * FROM users LIMIT 2;
+----+----------+----------+-----+------+
| id | username | password | age | sex |
+----+----------+----------+-----+------+
| 1 | hua | 123 | 27 | 0 |
| 2 | hao | 123 | 36 | 0 |
+----+----------+----------+-----+------+
2 rows in set (0.00 sec)

可以看出只返回了两条数据。
如果我想返回某个位置到另一个位置的记录呢?

1
2
3
4
5
6
7
8
9
10
11
mysql> SELECT * FROM users LIMIT 3,5;
+----+----------+----------------------------------+-----+------+
| id | username | password | age | sex |
+----+----------+----------------------------------+-----+------+
| 4 | yuan | 123 | 36 | 0 |
| 6 | ye | 123 | 34 | 0 |
| 7 | chun | 202cb962ac59075b964b07152d234b70 | 13 | 0 |
| 8 | tian | 1233 | 22 | 0 |
| 9 | hui | 345 | 18 | 0 |
+----+----------+----------------------------------+-----+------+
5 rows in set (0.00 sec)

注意:select 语句记录从0开始编号(0,1,2,3,4···)为第1、2、3、4、5···条记录,并且与id号无关,也就是说查询的id号和结果集没有任何的联系,只要排在结果集中第一个位置,那么它就是0,排在第二个位置就是1。
如果只添加一个数字,它表示从第一条记录开始返回,返回这个数字的数据数,如果返回第三条和第四条数据,就需要告诉从第几条返回,返回几条。拓展:在以后PHP当中,进行分页的时候,就会利用LIMIT语句来进行分页效果的实现,在分页效果实现当中,偏移值的计算公式是已经计算好的,计算公式就是当前括号中的页码减1*每一页显示的记录数。

2)将查询结果插入另一个数据表

INSERT [INTO] tb1_name [(col_name, …)] SELECT col_name FROM tb2_name …
它可以将查找的结果,存储到指定的数据表。
首先再创建一个新的数据表:

1
2
3
4
5
mysql> CREATE TABLE test(
-> id TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
-> username VARCHAR(20)
-> );
Query OK, 0 rows affected (0.04 sec)

下面我们将users表中age大于30的username写入到新建的test表中的username

1
2
mysql> INSERT test SELECT username FROM users WHERE age>30;
ERROR 1136 (21S01): Column count doesn't match value count at row 1

出现错误
注意:因为test表中需要插入的只有一个字段,所以SELECT结果集中也只有一个字段,在插入时要指定test表中指定字段,因为test表中有两个字段,即使是主键自增也不可以。
下面我们知道test表中的username:

1
2
3
mysql> INSERT test(username) SELECT username FROM users WHERE age>30;
Query OK, 3 rows affected (0.03 sec)
Records: 3 Duplicates: 0 Warnings: 0

查看一下:

1
2
3
4
5
6
7
8
9
mysql> SELECT * FROM test;
+----+----------+
| id | username |
+----+----------+
| 1 | hao |
| 2 | yuan |
| 3 | ye |
+----+----------+
3 rows in set (0.00 sec)

将age大于30的username插入到了test表中。

小结

数据记录的操作:增:INSERT 更:UPDATE 删:DELETE 查:SELECT
1. 增 INSERT:可以通过三种方法进行记录的插入,分别为
普通INSERT
INSERT SET
INSERT SELECT语句
(1) INSERT [INTO] tb1_name [(col_name,…)] {VALUES | VALUE} ({expr | DEFUALT},…),(…),…
注意:如果col_name被省略,意味着所有的列都要依次被赋值,不可以省略;
对于默认编号(AUTO_INCREMENT)的字段,使用NULL/DEFUALT进行插入;
而且插入的记录是识别算术,函数和字符表达式的
(2)INSERT [INTO] tb1_name SET col1_name={expr | DEFAULT}, …
如:INSERT users2 SET username=’xxx’,password=’xxx’;
说明与第一种不同之处在于:此方法可以使用子查询(SubQuery)
(3)INSERT [INTO] tb1_name [(col_name, …)] SELECT …
此方法可以将查询结果插入到指定数据表中

2. 更 UPDATE:实际有两种更新语句,单表更新和多表更新(详见第五章)

3. 删 DELETE:存在两种语法结构,单表删除、多表删除。
单表删除:
DELETE FROM tb1_name [WHERE where_condition]

如:删除第五条记录:DELETE FROM users WHERE id = 5; 而后再添加记录,那么该条记录不会填充到第六条,而是以顺序填到最后一个

条件表达式
对记录进行过滤,如果没有指定WHERE子句,则显示所有记录。
在WHERE表达式中,可以使用MySQL支持的函数或运算符。

4. 查 select select_expr
[
from table_references 表的参照
[where where_condition] 条件
[group by {col_name|position} [asc|sesc],…记录的分组
[having where_condition] 分组时对分组的条件进行设定
[order by {col_name|expr|position} [asc|desc]…]对于结果进行排序
[limit {[offset,]row_count|row_count OFFSET offset}]限制返回结果的数量
]
(1)常规
SELECT后面可以省略:如SELECT VERSION();/SELECT NOW();/SELECT 3+5;/SELECT id,username FROM users;/SELECT username,id FROM users;

所以查询顺序影响结果的输出顺序!!!

  • 表示所有的列

可以在查询的列前面加上表名+. 如:SELECT users.id,user2.password FROM users;

当列名称复杂时可以用别名:如 SELECT users.id AS usersid, users.username AS uname FROM users;(注意一下AS)

所以查询的别名也影响输出结果的列名!!!
(2)分组
查询结果分组:[GROUP BY {col_name | position} [ASC | DESC], … ]

ASC 升序;DESC 降序;

如:SELECT sex FROM users GROUP BY sex/“位置”; 查看性别的分组结果。(一般指定名称就行)

在GROUP BY 进行分组的时候,还可以进行设置分组条件:[HAVING where_condition]

如:SELECT sex FROM users GROUP BY 1 HAVING age > 35; 这个语句错误,原因是sex里面没有age,所以更正为:SELECT sex,age FROM users GROUP BY 1 HAVING age > 35;或者采用聚合函数(max,min,sum等) 如
SELECT password FROM users GROUP BY 1 HAVING AVG(age)>10;
GROUP BY的规定:
1、GROUP BY 后面可以包含多个列,这就是嵌套。
2、如果GROUP BY进行了嵌套,数据将在最后一个分组上进行汇总。
3、GROUP BY子句中列出来的每个列必须是检索列或有效的表达式(但不能是聚集函数),如果在SELECT中使用了表达式,则必须在GROUP BY子句中指定相同的表达式。不能使用别名。
4、除了聚集语句外,SELECT语句中的每一个列都必须在GROUP BY子句中给出。
5、如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多个NULL,它们将作为一个分组返回。
6、GROUP BY子句必须在WHERE 子句之后,ORDER BY 子句之前。
(3)排序
还可以对查询分组的结果进行排序:

[ORDER BY {col_name | expr | position} [ASC | DESC], …]

如:SELECT * FROM users ORDER BY id, age DESC; 默认是升序。

除了返回记录的排序还可以对记录进行限制查询结果的数量:

[LIMIT {[offset,] row_count | row_count OFFSET offset}]

如:SELECT * FROM users LIMIT 2; 返回两条记录;

SELECT * FROM users LIMIT 2,2;返回的是偏移值(索引号)为2的记录开始的两条记录(不管升序还是降序,第一条记录的索引号都是0);

(4)插入记录
INSERT [INTO] tb1_name [(col_name, …)] SELECT col_name FROM tb2_name …
说明:将查询结果插入到指定数据表的列

如:INSERT test(username) SELECT username FROM users WHERE age >= 30; 查找username表里的age>=30的username,插入到test表中的username列————综合一点的