您的位置:首页 > 数据库 > MySQL

慢谈MYSQL常用SQL语句

2015-04-22 11:42 239 查看
目录

1、SQL语句分类

2、DDL语句

3、DML语句

4、DCL语句

5、事务相关语句

6、mysql查询

6.1、单表简单查询

6.2、多表组合查询

6.2.1、联结查询(交叉联结,内联结,外联结(左外联结、右外联结))

6.2.2、联合查询(UNION)

6.2.3、内联结

6.3、子查询

6.3.1、WHERE子查询

6.3.2、FROM子查询

1、SQL语句分类

DDL:数据定义语言,用来定义数据库对象,包括数据库、表、索引、存储过程、存储函数、约束、触发器、事件调度器等

DML:数据操作语言,包括CRUD(Insert,Select,Replace,Update,Delete)

DCL:数据控制语言,包括grant,revoke

与事务相关的语言:starttransaction,commit,rollback,savepoint

2、DDL语句

2.1、数据库操作

a)、创建数据库:

语法:mysql>create{database|schema}[ifnotexists]数据库名;#“ifnotexists”是用来作条件判断

举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mysql>createdatabase
if
notexistsmydb;
#创建一个mydb数据库

QueryOK,1rowaffected(0.00sec)

mysql>showdatabases;

+--------------------+

|Database|

+--------------------+

|information_schema|

|mydb|

|mysql|

|performance_schema|

|
test
|

+--------------------+

5rows
in
set
(0.00sec)

mysql>createschema
if
notexistsmydb;
#尝试再次建立mydb数据库

QueryOK,1rowaffected,1warning(0.00sec)

mysql>showwarnings;
#查看警告信息

+-------+------+-----------------------------------------------+

|Level|Code|Message|

+-------+------+-----------------------------------------------+

|Note|1007|Can
'tcreatedatabase'
mydb';databaseexists|

+-------+------+-----------------------------------------------+

1row
in
set
(0.00sec)


b)、删除数据库:

语法:

mysql>drop{database|schema}[ifexists]数据库名;

举例:

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

+--------------------+

|Database|

+--------------------+

|information_schema|

|mydb|

|mysql|

|performance_schema|

|
test
|

+--------------------+

5rows
in
set
(0.00sec)

mysql>dropschema
if
existsmydb;

QueryOK,0rowsaffected(0.00sec)

mysql>showdatabases;

+--------------------+

|Database|

+--------------------+

|information_schema|

|mysql|

|performance_schema|

|
test
|

+--------------------+

4rows
in
set
(0.00sec)


c)、修改数据库

语法:

mysql>alter{database|schema}数据库名[DEFAULT]CHARACTERSET[=]charset_name|[DEFAULT]COLLATE[=]collation_name

mysql>alter{database|schema}数据库名upgradedatadirectoryname;#此语句用在数据进行升级后用来升级数据字典

2.2、数据表操作

a)、创建字段自定义表

语法:

mysql>createtable[ifnotexists]表名(字段1字段定义,字段2字段定义,...)众多选项

mysql>helpcreatetable;#获取表创建的帮助。

举例:

1
2
mysql>use
test
;

mysql>createtable
if
notexiststb1(
id
intunsignedauto_incrementprimarykey,namechar(30)notnull,agetinyintunsigned,classchar(20)notnull)character
set
=utf8engine=innodb;


以下三个sql语句都可查数据库中的表状态:

1
2
3
mysql>showtablestatusfrom
test
\G

mysql>showtablestatus
in
test
\G

mysql>showtablestatuslike
'tb1'
;


b)、以select语句查询到的数据为结果来创建一张表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql>usemydb1;

mysql>createtable
if
notexiststb2
select
user,host,passwordfrommysql.user;

QueryOK,3rowsaffected(0.02sec)

Records:3Duplicates:0Warnings:0

mysql>
select
*fromtb2;

+------+------------+-------------------------------------------+

|user|host|password|

+------+------------+-------------------------------------------+

|root|localhost|*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9|

|root|db\_server|*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9|

|root|127.0.0.1|*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9|

+------+------------+-------------------------------------------+

3rows
in
set
(0.00sec)

注:这种方式创建出来的表,表的表结构与源表的表结构是不同的,也就是说字段中的定义和修饰符不会全部在新表中都有


c)、模仿一张表的表结构来创建一张只有表结构的表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mysql>createtable
if
notexiststb3liketb2;

QueryOK,0rowsaffected(0.03sec)

mysql>desctb3;

+----------+----------+------+-----+---------+-------+

|Field|Type|Null|Key|Default|Extra|

+----------+----------+------+-----+---------+-------+

|user|char(16)|NO||||

|host|char(60)|NO||||

|password|char(41)|NO||||

+----------+----------+------+-----+---------+-------+

3rows
in
set
(0.03sec)

mysql>desctb2;

+----------+----------+------+-----+---------+-------+

|Field|Type|Null|Key|Default|Extra|

+----------+----------+------+-----+---------+-------+

|user|char(16)|NO||||

|host|char(60)|NO||||

|password|char(41)|NO||||

+----------+----------+------+-----+---------+-------+

3rows
in
set
(0.00sec)

mysql>
select
*fromtb3;
#tb3中是没有数据的

Empty
set
(0.02sec)


开动脑筋:

怎样从一个表中挑选一些数据生成一张新表,且新表的表结构(字段定义、修饰符等)与源表是完成相同的。

实现方式分两部来完成,先创建和源表一样表结构的表,再以select的方式插入数据到此表。

实现:

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
mysql>DESCtb1;

+-------+---------------------+------+-----+---------+----------------+

|Field|Type|Null|Key|Default|Extra|

+-------+---------------------+------+-----+---------+----------------+

|
id
|int(10)unsigned|NO|PRI|NULL|auto_increment|

|name|char(20)|NO||NULL||

|age|tinyint(3)unsigned|NO||NULL||

+-------+---------------------+------+-----+---------+----------------+

3rows
in
set
(0.00sec)

mysql>SELECT*FROMtb1;

+----+-------+-----+

|
id
|name|age|

+----+-------+-----+

|1|jack|29|

|2|jason|39|

|3|tom|37|

|4|luck|22|

|7|root|0|

|8|root|0|

|9|root|0|

+----+-------+-----+

7rows
in
set
(0.01sec)

mysql>CREATETABLEIFNOTEXISTStb2LIKEtb1;
#创建tb2以tb1的表结构为源

QueryOK,0rowsaffected,1warning(0.01sec)

mysql>DESCtb2;
#tb2的表结构和tb1的表结构是完成相同的

+-------+---------------------+------+-----+---------+----------------+

|Field|Type|Null|Key|Default|Extra|

+-------+---------------------+------+-----+---------+----------------+

|
id
|int(10)unsigned|NO|PRI|NULL|auto_increment|

|name|char(20)|NO||NULL||

|age|tinyint(3)unsigned|NO||NULL||

+-------+---------------------+------+-----+---------+----------------+

3rows
in
set
(0.00sec)

mysql>INSERTINTOtb2SELECT*FROMtb1WHEREage>30;
#只把tb1中年龄大于30的数据插入到新表中

QueryOK,2rowsaffected(0.02sec)

Records:2Duplicates:0Warnings:0

mysql>SELECT*FROMtb2;
#验证数据

+----+-------+-----+

|
id
|name|age|

+----+-------+-----+

|2|jason|39|

|3|tom|37|

+----+-------+-----+

2rows
in
set
(0.00sec)

这样就可实现保持源表的表结构提取所需数据。


d)、删除表

mysql>droptable[ifexists]表名;

e)、修改表名称、字段、定义、修饰符等

用helpaltertable来获取帮助

新增字段,删除字段

modify修改指定字段定义:

change修改字段名

rename新表名

举例:

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
mysql>SELECT*FROMtb2;

+------+------+

|
id
|name|

+------+------+

|1|Zcj|

|2|Tom|

+------+------+

2rows
in
set
(0.00sec)

mysql>DESCtb2;

+-------+----------+------+-----+---------+-------+

|Field|Type|Null|Key|Default|Extra|

+-------+----------+------+-----+---------+-------+

|
id
|int(11)|YES||NULL||

|name|char(30)|YES||NULL||

+-------+----------+------+-----+---------+-------+

mysql>ALTERTABLEtb2ADDAgeTINYINTUNSIGNEDAFTER
id
;

#增加“Age”字段

QueryOK,2rowsaffected(0.04sec)

Records:2Duplicates:0Warnings:0

mysql>SELECT*FROMtb2;

+------+------+------+

|
id
|Age|name|

+------+------+------+

|1|NULL|Zcj|

|2|NULL|Tom|

+------+------+------+

mysql>ALTERTABLEtb2DROPAge;

#删除字段“Age”

QueryOK,2rowsaffected(0.06sec)

Records:2Duplicates:0Warnings:0

mysql>SELECT*FROMtb2;

+------+------+

|
id
|name|

+------+------+

|1|Zcj|

|2|Tom|

+------+------+

mysql>ALTERTABLEtb2MODIFY
id
INTUNSIGNEDNOTNULLAUTO_INCREMENTPRIMARYKEY;

#修改id字段的定义

QueryOK,2rowsaffected(0.01sec)

Records:2Duplicates:0Warnings:0

mysql>DESCtb2;

+-------+------------------+------+-----+---------+----------------+

|Field|Type|Null|Key|Default|Extra|

+-------+------------------+------+-----+---------+----------------+

|
id
|int(10)unsigned|NO|PRI|NULL|auto_increment|

|name|char(30)|YES||NULL||

+-------+------------------+------+-----+---------+----------------+

mysql>ALTERTABLEtb2CHANGEnamefullnameCHAR(50)NOTNULL;

#修改字段name的名称及定义

QueryOK,2rowsaffected(0.01sec)

Records:2Duplicates:0Warnings:0

mysql>DESCtb2;

+----------+------------------+------+-----+---------+----------------+

|Field|Type|Null|Key|Default|Extra|

+----------+------------------+------+-----+---------+----------------+

|
id
|int(10)unsigned|NO|PRI|NULL|auto_increment|

|fullname|char(50)|NO||NULL||

+----------+------------------+------+-----+---------+----------------+

mysql>ALTERTABLEtb2RENAMEnewtb2;

#修改表名

QueryOK,0rowsaffected(0.00sec)

mysql>DESCnewtb2;

+----------+------------------+------+-----+---------+----------------+

|Field|Type|Null|Key|Default|Extra|

+----------+------------------+------+-----+---------+----------------+

|
id
|int(10)unsigned|NO|PRI|NULL|auto_increment|

|fullname|char(50)|NO||NULL||

+----------+------------------+------+-----+---------+----------------+


3、DML语句

3.1、insert:用来插入数据

语法:

mysql>insertinto表名[(字段名,...)]{values|value}(值,...)

mysql>insertinto表名set字段名=值,...

举例:

1
mysql>CREATETABLEIFNOTEXISTStb1(
id
intunsignedauto_incrementprimarykey,namechar(20)notnull,agetinyintunsignednotnull);
#先创建一张表


a)、插入多行数据

1
mysql>INSERTINTOtb1(name,age)VALUES(
'jack'
,29),(
'jason'
,39),(
'tom'
,37);


b)、插入一行数据

1
2
3
4
5
6
7
8
9
10
11
mysql>INSERTINTOtb1SETname=
'luck'
,age=22;

mysql>SELECT*FROMtb1;
#查看表数据

+----+-------+-----+

|
id
|name|age|

+----+-------+-----+

|1|jack|29|

|2|jason|39|

|3|tom|37|

|4|luck|22|

+----+-------+-----+

4rows
in
set
(0.00sec)


c)、以select结果插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql>INSERTINTOtb1(name)SELECTuserFROMmysql.user;
#把user表中的用户信息检索出来填充到tb1表中的name字段

QueryOK,3rowsaffected,1warning(0.08sec)

Records:3Duplicates:0Warnings:1

mysql>SHOWWARNINGS;
#有个警告信息,因为创建表时age字段是notnull的,只填充了name字段,没有age字段的相应数据

+---------+------+------------------------------------------+

|Level|Code|Message|

+---------+------+------------------------------------------+

|Warning|1364|Field
'age'
doesn'thaveadefaultvalue|

+---------+------+------------------------------------------+

1row
in
set
(0.00sec)

mysql>SELECT*FROMtb1;
#自动把age字段填充为0

+----+-------+-----+

|
id
|name|age|

+----+-------+-----+

|1|jack|29|

|2|jason|39|

|3|tom|37|

|4|luck|22|

|7|root|0|

|8|root|0|

|9|root|0|

+----+-------+-----+

7rows
in
set
(0.08sec)


3.2、replace:用来替换表的数据,如果源表中没有此数据则增加数据

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
mysql>DESCtb2;
#name字段是唯一键索引

+-------+---------------------+------+-----+---------+----------------+

|Field|Type|Null|Key|Default|Extra|

+-------+---------------------+------+-----+---------+----------------+

|
id
|int(10)unsigned|NO|PRI|NULL|auto_increment|

|name|char(20)|NO|UNI|NULL||

|age|tinyint(3)unsigned|NO||NULL||

+-------+---------------------+------+-----+---------+----------------+

3rows
in
set
(0.00sec)

mysql>SELECT*FROMtb2;

+----+-------+-----+

|
id
|name|age|

+----+-------+-----+

|1|jack|29|

|2|jason|39|

|3|tom|37|

|4|luck|22|

+----+-------+-----+

4rows
in
set
(0.00sec)

mysql>REPLACEINTOtb2SETname=
'jack'
,age=33;
#因原表中有jack这个用户,replace这个命令会先删除原来的那一行,再新增加一行,所以会有两行受到影响

QueryOK,2rowsaffected(0.04sec)

mysql>REPLACEINTOtb2SETname=
'zhaochj'
,age=29;
#因原表中没有zhaochj这个用户,所以直接在最后增加

QueryOK,1rowaffected(0.03sec)

mysql>SELECT*FROMtb2;

+----+---------+-----+

|
id
|name|age|

+----+---------+-----+

|2|jason|39|

|3|tom|37|

|4|luck|22|

|5|jack|33|

|6|zhaochj|29|

+----+---------+-----+

5rows
in
set
(0.02sec)


3.3、update:修改表中的数据

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
mysql>SELECT*FROMtb2;

+----+---------+-----+

|
id
|name|age|

+----+---------+-----+

|2|jason|39|

|3|tom|37|

|4|luck|22|

|5|jack|33|

|6|zhaochj|29|

+----+---------+-----+

5rows
in
set
(0.02sec)

mysql>UPDATEtb2SETage=33WHEREname=
'zhaochj'
;

QueryOK,1rowaffected(0.01sec)

Rowsmatched:1Changed:1Warnings:0

mysql>UPDATEtb2SETage=11LIMIT2;
#修改前两行的年龄为11

QueryOK,2rowsaffected(0.01sec)

Rowsmatched:2Changed:2Warnings:0

mysql>SELECT*FROMtb2;

+----+---------+-----+

|
id
|name|age|

+----+---------+-----+

|2|jason|11|

|3|tom|11|

|4|luck|22|

|5|jack|33|

|6|zhaochj|33|

+----+---------+-----+

5rows
in
set
(0.02sec)


3.4、delete删除表中数据

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
mysql>SELECT*FROMtb2;

+----+---------+-----+

|
id
|name|age|

+----+---------+-----+

|2|jason|11|

|3|tom|11|

|4|luck|22|

|5|jack|33|

|6|zhaochj|33|

+----+---------+-----+

5rows
in
set
(0.02sec)

mysql>

mysql>DELETEFROMtb2WHEREname=
'zhaochj'
;
#加上where子句限定删除的范围

QueryOK,1rowaffected(0.38sec)

mysql>SELECT*FROMtb2;

+----+-------+-----+

|
id
|name|age|

+----+-------+-----+

|2|jason|11|

|3|tom|11|

|4|luck|22|

|5|jack|33|

+----+-------+-----+

4rows
in
set
(0.00sec)

mysql>DELETEFROMtb2;
#这样直接把表中的数据全部删除

QueryOK,4rowsaffected(0.01sec)

mysql>SELECT*FROMtb2;

Empty
set
(0.00sec)

mysql>INSERTINTOtb2(name,age)VALUES(
'zcj'
,29);
#试着插入一行数据

QueryOK,1rowaffected(0.01sec)

mysql>SELECT*FROMtb2;
#查看数据发现id号不是从"1"开始的,这是因为字段“id”被定义成了“auto_increment”了

+----+------+-----+

|
id
|name|age|

+----+------+-----+

|7|zcj|29|

+----+------+-----+

1row
in
set
(0.03sec)

mysql>TRUNCATETABLEtb2;
#清空一张表,应该用这个命令,表示重置表,会清空“auto_increment”的计数器

QueryOK,0rowsaffected(0.05sec)

mysql>INSERTINTOtb2(name,age)VALUES(
'zcj'
,29);

QueryOK,1rowaffected(0.03sec)

mysql>SELECT*FROMtb2;
#id号又从“1”开始

+----+------+-----+

|
id
|name|age|

+----+------+-----+

|1|zcj|29|

+----+------+-----+

1row
in
set
(0.00sec)


4、DCL语句

4.1、权限赋予

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
mysql>GRANT
select
ONmydb2.tb1TO
'mydb2user1'
@
'%'
IDENTIFIEDBY
'111111'
;

#对mydb2数据库中的tb1表授予mydb2user1用户可在任意主机以6个1为密码登陆,但权限只有select

mysql>SHOWGRANTSFORmydb2user1;
#显示mydb2user1用户的权限信息

+-----------------------------------------------------------------------------------------------------------+

|Grants
for
mydb2user1@%|

+-----------------------------------------------------------------------------------------------------------+

|GRANTUSAGEON*.*TO
'mydb2user1'
@
'%'
IDENTIFIEDBYPASSWORD
'*FD571203974BA9AFE270FE62151AE967ECA5E0AA'
|

|GRANTSELECTON`mydb2`.`tb1`TO
'mydb2user1'
@
'%'
|

+-----------------------------------------------------------------------------------------------------------+

2rows
in
set
(0.00sec)

验证权限是否生效:

[root@mariadb~]
#mysql-umydb2user1-p111111#以mydb2user1登陆

mysql>SHOWDATABASES;

+--------------------+

|Database|

+--------------------+

|information_schema|

|mydb2|

|
test
|

+--------------------+

mysql>USEmydb2;

Databasechanged

mysql>SHOWTABLES;

+-----------------+

|Tables_in_mydb2|

+-----------------+

|tb1|

+-----------------+

mysql>SELECT*FROMtb1;

+------+------+

|
id
|name|

+------+------+

|1|Zcj|

|2|Tom|

|3|Jack|

+------+------+

mysql>INSERTINTOtb1(
id
,name)VALUES(4,
'Cora'
);
#没有权限插入数据

ERROR1142(42000):INSERT
command
deniedtouser
'mydb2user1'
@
'localhost'
for
table
'tb1'

mysql>GRANTinsertONmydb2.tb1TO
'mydb2user1'
@
'%'
;
#再赋予insert权限

QueryOK,0rowsaffected(0.00sec)

mysql>SHOWGRANTSFORmydb2user1;

+-----------------------------------------------------------------------------------------------------------+

|Grants
for
mydb2user1@%|

+-----------------------------------------------------------------------------------------------------------+

|GRANTUSAGEON*.*TO
'mydb2user1'
@
'%'
IDENTIFIEDBYPASSWORD
'*FD571203974BA9AFE270FE62151AE967ECA5E0AA'
|

|GRANTSELECT,INSERTON`mydb2`.`tb1`TO
'mydb2user1'
@
'%'
|

+-----------------------------------------------------------------------------------------------------------+

2rows
in
set
(0.00sec)

[root@mariadb~]
#mysql-umydb2user1-p111111#再以mydb2user1登陆

mysql>INSERTINTOtb1(
id
,name)VALUES(4,
'Cora'
);

QueryOK,1rowaffected(0.07sec)

mysql>SELECT*FROMtb1;
#数据已插入

+------+------+

|
id
|name|

+------+------+

|1|Zcj|

|2|Tom|

|3|Jack|

|4|Cora|

+------+------+

4rows
in
set
(0.00sec)


4.2、回收权限

1
2
3
4
5
6
[root@mariadb~]
#mysql-uroot-p123456#以root登陆

mysql>REVOKEinsertONmydb2.tb1FROMmydb2user1;

QueryOK,0rowsaffected(0.00sec)

[root@mariadb~]
#mysql-umydb2user1-p111111#以mydb2user1登陆

mysql>INSERTINTOmydb2.tb1(
id
,name)VALUES(5,
'Lucky'
);
#无法插入数据,insert权限已被回收

ERROR1142(42000):INSERT
command
deniedtouser
'mydb2user1'
@
'localhost'
for
table
'tb1'


5、事务相关语句

mysql>STARTTRANSACTION;#开始事务

mysql>SAVEPOINTpoint_name;#保存一个事务的位置,以方便撤销事务

mysql>ROLLBACKTOpoint_name;#回滚到一个点

mysql>ROLLBACK;#回滚到开始事务时的状态

mysql>COMMIT;#提交事务

举例:

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
mysql>STARTTRANSACTION;

#开始事务

QueryOK,0rowsaffected(0.02sec)

mysql>SELECT*FROMtb1;

+------+------+

|
id
|name|

+------+------+

|1|Zcj|

|2|Tom|

|3|Jack|

|4|Cora|

+------+------+

4rows
in
set
(0.00sec)

mysql>INSERTINTOtb1(
id
,name)VALUES(5,
'Lucky'
);

#插入一行数据

QueryOK,1rowaffected(0.00sec)

mysql>SELECT*FROMtb1;

+------+-------+

|
id
|name|

+------+-------+

|1|Zcj|

|2|Tom|

|3|Jack|

|4|Cora|

|5|Lucky|

+------+-------+

5rows
in
set
(0.00sec)

mysql>SAVEPOINTp1;

#在有id为5这行数据时创建一个保存点

QueryOK,0rowsaffected(0.01sec)

mysql>DELETEFROMtb1WHERE
id
=2;

#删除一行数据

QueryOK,1rowaffected(0.00sec)

mysql>SELECT*FROMtb1;

+------+-------+

|
id
|name|

+------+-------+

|1|Zcj|

|3|Jack|

|4|Cora|

|5|Lucky|

+------+-------+

4rows
in
set
(0.00sec)

mysql>ROLLBACKTOp1;

#回滚到保存点p1的状态

QueryOK,0rowsaffected(0.00sec)

mysql>SELECT*FROMtb1;

+------+-------+

|
id
|name|

+------+-------+

|1|Zcj|

|2|Tom|

|3|Jack|

|4|Cora|

|5|Lucky|

+------+-------+

5rows
in
set
(0.00sec)

mysql>ROLLBACK;

#回滚到事务开始时的状态

QueryOK,0rowsaffected(0.00sec)

mysql>SELECT*FROMtb1;

+------+------+

|
id
|name|

+------+------+

|1|Zcj|

|2|Tom|

|3|Jack|

|4|Cora|

+------+------+

4rows
in
set
(0.00sec)

mysql>COMMIT;

#提交事务

QueryOK,0rowsaffected(0.00sec)


6、mysql查询

为演示各种SELECT语句,建立以下几个表:

一)、表名为“students_tb”,字段为:StudentID,Name,Age,Gender,ClassID,分别存放学生的名字、年龄、性别、有班级的ID号,具体的班级存放在另一张表中

二)、表名为“classes_tb”,字段为:ClassID,Class,TeacherID,分别存放班级的ID号,具体的班级名,这个班级是哪个老师负责的ID号,具体的负责的老师存放在另一张表中

三)、表名为“teacher_tb”,字段为:TeacheID,Name,Age,Gender,分别存放老师的ID号,老师的名字,年龄,性别

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
mysql>USEmydb1;

mysql>CREATETABLEIFNOTEXISTSstudents_tb(StudentIDSMALLINTUNSIGNEDNOTNULLAUTO_INCREMENTPRIMARYKEY,NameCHAR(30)NOTNULL,AgeTINYINTUNSIGNED,GenderENUM(
'M'
,
'F'
),ClassIDTINYINTUNSIGNEDNOTNULL);

mysql>INSERTINTOstudents_tb(Name,Age,Gender,ClassID)VALUES(
'Tom'
,17,
'M'
,1),(
'Jack'
,18,
'M'
,3),(
'Lucy'
,21,
'F'
,6),(
'Jimima'
,15,
'F'
,4),(
'Jimmy'
,30,
'M'
,9),(
'Jim'
,26,
'M'
,7);

mysql>SELECT*FROMstudents_tb;

+-----------+--------+------+--------+---------+

|StudentID|Name|Age|Gender|ClassID|

+-----------+--------+------+--------+---------+

|1|Tom|17|M|1|

|2|Jack|18|M|3|

|3|Lucy|21|F|6|

|4|Jimima|15|F|4|

|5|Jimmy|30|M|9|

|6|Jim|26|M|7|

+-----------+--------+------+--------+---------+

mysql>CREATETABLEIFNOTEXISTSclasses_tb(ClassIDTINYINTUNSIGNEDNOTNULLAUTO_INCREMENTPRIMARYKEY,ClassCHAR(20)NOTNULL,TeacherIDTINYINTUNSIGNEDNOTNULL);

mysql>ALTERTABLEclasses_tbADDUNIQUEKEY(Class);
#这个表中的班别应该是唯一的,所以用此sql语句来修改

QueryOK,0rowsaffected(0.08sec)

Records:0Duplicates:0Warnings:0

mysql>DESCclasses_tb;

+-----------+---------------------+------+-----+---------+----------------+

|Field|Type|Null|Key|Default|Extra|

+-----------+---------------------+------+-----+---------+----------------+

|ClassID|tinyint(3)unsigned|NO|PRI|NULL|auto_increment|

|Class|char(20)|NO|UNI|NULL||

|TeacherID|tinyint(3)unsigned|NO||NULL||

+-----------+---------------------+------+-----+---------+----------------+

3rows
in
set
(0.00sec)

mysql>INSERTINTOclasses_tb(Class,TeacherID)VALUES(
'class1'
,5),(
'class2'
,2),(
'class3'
,5),(
'class4'
,2),(
'class5'
,4),(
'class6'
,1);

mysql>SELECT*FROMclasses_tb;

+---------+--------+-----------+

|ClassID|Class|TeacherID|

+---------+--------+-----------+

|1|class1|5|

|2|class2|2|

|3|class3|5|

|4|class4|2|

|5|class5|4|

|6|class6|1|

+---------+--------+-----------+

mysql>CREATETABLEIFNOTEXISTSteacher_tb(TeacherIDTINYINTUNSIGNEDNOTNULLAUTO_INCREMENTPRIMARYKEY,NameCHAR(30)NOTNULL,AgeTINYINTUNSIGNED,GenderENUM(
'M'
,
'F'
));

mysql>INSERTINTOteacher_tb(Name,Age,Gender)VALUES(
'Wangbaoqiang'
,30,
'M'
),(
'Zhangshanfeng'
,32,
'F'
),(
'Zhaoqiang'
,40,
'M'
),(
'Yinghui'
,50,
'M'
),(
'Fengbing'
,46,
'M'
),(
'Qianqiang'
,37,
'M'
),(
'Shunbin'
,68,
'M'
);

mysql>SELECT*FROMteacher_tb;

+-----------+----------------+------+--------+

|TeacherID|Name|Age|Gender|

+-----------+----------------+------+--------+

|1|Wangbaoqiang|30|M|

|2|Zhangshanfeng|32|F|

|3|Zhaoqiang|40|M|

|4|Yinghui|50|M|

|5|Fengbing|46|M|

|6|Qianqiang|37|M|

|7|Shunbin|68|M|

+-----------+----------------+------+--------+

三个表创建及数据插入完成。


6.1、单表简单查询

语法:

SELECT字段,字段,...FROM表名WHERE子句;

举例:

查询students_tb表中前5个学生的姓名和年龄

1
2
3
4
5
6
7
8
9
10
mysql>SELECTName,AgeFROMstudents_tbLIMIT5;

+--------+------+

|Name|Age|

+--------+------+

|Tom|17|

|Jack|18|

|Lucy|21|

|Jimima|15|

|Jimmy|30|

+--------+------+


a)、比较运算:>,<,>=,<=,!=,<>,<=>

在students_tb表中查询年龄大于20的学生有哪些:

1
2
3
4
5
6
7
8
mysql>SELECTName,AgeFROMstudents_tbWHEREAge>20;

+-------+------+

|Name|Age|

+-------+------+

|Lucy|21|

|Jimmy|30|

|Jim|26|

+-------+------+


在students_tb表中查询年龄不等于30的学生有哪些:

1
2
3
4
5
6
7
8
9
10
mysql>SELECTName,AgeFROMstudents_tbWHEREAge!=30;

+--------+------+

|Name|Age|

+--------+------+

|Tom|17|

|Jack|18|

|Lucy|21|

|Jimima|15|

|Jim|26|

+--------+------+


在students_tb表中查询年龄不等于30和不等于15的学生有哪些:

1
2
3
4
5
6
7
8
9
mysql>SELECTName,AgeFROMstudents_tbWHEREAge!=30andAge!=15;

+------+------+

|Name|Age|

+------+------+

|Tom|17|

|Jack|18|

|Lucy|21|

|Jim|26|

+------+------+


b)、BETWEEN...AND..表示在一个范围内的数据

在students_tb表中查询年龄在20到30之间的学生:

1
2
3
4
5
6
7
8
mysql>SELECTName,AgeFROMstudents_tbWHEREAgeBETWEEN20AND30;

+-------+------+

|Name|Age|

+-------+------+

|Lucy|21|

|Jimmy|30|

|Jim|26|

+-------+------+


c)、IN(元素,...),表示在一个范围内匹配

在students_tb表中查询年龄是18或26或30的学生:

1
2
3
4
5
6
7
8
mysql>SELECTName,AgeFROMstudents_tbWHEREAgeIN(18,26,30);
#表示查询一个集合内的数据

+-------+------+

|Name|Age|

+-------+------+

|Jack|18|

|Jimmy|30|

|Jim|26|

+-------+------+


d)、LIKE子句与RLIKE子句

在students_tb表中查询姓名中有字母“J”,且在后边跟了任意个字符的用户:

1
2
3
4
5
6
7
8
9
10
mysql>SELECTName,AgeFROMstudents_tbWHERENameLIKE
'J%'
;

+--------+------+

|Name|Age|

+--------+------+

|Jack|18|

|Jimima|15|

|Jimmy|30|

|Jim|26|

+--------+------+

#通配符匹配有“%”,“_”,“%”表示匹配任意个任意字符,“_”表示匹配任意单个字符


在students_tb表中查询姓名以“J”开头,后接任意字符,再接有一个m或多个m,再后接任意个字符,并且以y结尾的学生:

1
2
3
4
5
6
mysql>SELECTName,AgeFROMstudents_tbWHERENameRLIKE
'^J.*m+.*y$'
;
#正则匹配

+-------+------+

|Name|Age|

+-------+------+

|Jimmy|30|

+-------+------+


e)、逻辑运算符(NOT,AND,OR),优先级依次降低

在students_tb表中查询学生姓名以“J”开头,并且年龄大于20的信息:

1
2
3
4
5
6
7
mysql>SELECTName,AgeFROMstudents_tbWHERENameRLIKE
'^J'
&&Age>20;
#“&&”=“AND”

+-------+------+

|Name|Age|

+-------+------+

|Jimmy|30|

|Jim|26|

+-------+------+


在students_tb表中查询年龄是30或者是15的学生:

1
2
3
4
5
6
7
mysql>SELECTName,AgeFROMstudents_tbWHEREAge=30ORAge=15;
#“OR”="||"

+--------+------+

|Name|Age|

+--------+------+

|Jimima|15|

|Jimmy|30|

+--------+------+


在students_tb表中查询性别不是“F”的学生:

1
2
3
4
5
6
7
8
9
mysql>SELECTName,GenderFROMstudents_tbWHERENOTGender=
'F'
;

+-------+--------+

|Name|Gender|

+-------+--------+

|Tom|M|

|Jack|M|

|Jimmy|M|

|Jim|M|

+-------+--------+


在students_tb表中查询年龄在10到26之间,姓名以“J”或“L”开头的女生:

1
2
3
4
5
6
7
mysql>SELECTName,Age,GenderFROMstudents_tbWHEREAge>=10ANDAge<=26AND(NameLIKE
'J%'
ORNameLIKE
'%L'
)ANDGender=
'F'
;

+--------+------+--------+

|Name|Age|Gender|

+--------+------+--------+

|Jimima|15|F|

+--------+------+--------+

注:逻辑运算是有优先级的,如果不用括号那得到的结果与预想的不一样。


f)、聚合函数:MAX(),MIN(),AVG(),SUM(),COUNT()

在students_tb表中查询年龄最大的学生是谁:

1
2
3
4
5
6
mysql>SELECTName,AgeFROMstudents_tbWHEREAge=(SELECTMAX(Age)FROMstudents_tb);

+-------+------+

|Name|Age|

+-------+------+

|Jimmy|30|

+-------+------+


在students_tb表中查询年龄最小的学生是谁:

1
2
3
4
5
6
mysql>SELECTName,AgeFROMstudents_tbWHEREAge=(SELECTMIN(Age)FROMstudents_tb);

+--------+------+

|Name|Age|

+--------+------+

|Jimima|15|

+--------+------+


在students_tb表中求所有学生年龄的平均值

1
2
3
4
5
6
mysql>SELECTAVG(Age)FROMstudents_tb;

+----------+

|AVG(Age)|

+----------+

|21.1667|

+----------+


g)、GROUPBY分组,及HAVING子句

在students_tb表中求男生、女生年龄分别的平均值:

1
2
3
4
5
6
7
mysql>SELECTGender,AVG(Age)FROMstudents_tbGROUPBYGender;

+--------+----------+

|Gender|AVG(Age)|

+--------+----------+

|M|22.7500|

|F|18.0000|

+--------+----------+


显示students_tb表中分别显示男生,女生的最大年龄:

1
2
3
4
5
6
7
mysql>SELECTGender,MAX(Age)FROMstudents_tbGROUPBYGender;

+--------+----------+

|Gender|MAX(Age)|

+--------+----------+

|M|30|

|F|21|

+--------+----------+


为了演示HAVING子句,现在加入以下数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql>INSERTINTOstudents_tb(Name,Age,Gender,ClassID)VALUES(
'Cora'
,25,
'F'
,6),(
'Echo'
,58,
'F'
,7),(
'张三'
,47,
'M'
,3);

mysql>SELECT*FROMstudents_tb;

+-----------+--------+------+--------+---------+

|StudentID|Name|Age|Gender|ClassID|

+-----------+--------+------+--------+---------+

|1|Tom|17|M|1|

|2|Jack|18|M|3|

|3|Lucy|21|F|6|

|4|Jimima|15|F|4|

|5|Jimmy|30|M|9|

|6|Jim|26|M|7|

|7|Cora|25|F|6|

|8|Echo|58|F|7|

|9|张三|47|M|3|

+-----------+--------+------+--------+---------+


以班级排序,显示students_tb表中各个班级中年龄最小的同学,只显示年龄小于20的的班级:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql>SELECTClassID,Name,MIN(Age)FROMstudents_tbGROUPBYClassID;

+---------+--------+----------+

|ClassID|Name|MIN(Age)|

+---------+--------+----------+

|1|Tom|17|

|3|Jack|18|

|4|Jimima|15|

|6|Lucy|21|

|7|Jim|26|

|9|Jimmy|30|

+---------+--------+----------+

mysql>SELECTClassID,Name,MIN(Age)FROMstudents_tbGROUPBYClassIDHAVINGMIN(Age)<20;

+---------+--------+----------+

|ClassID|Name|MIN(Age)|

+---------+--------+----------+

|1|Tom|17|

|3|Jack|18|

|4|Jimima|15|

+---------+--------+----------+


h)、ORDERBY排序

以性别分组,分别计算男女生的年龄之和,并逆序排列:

1
2
3
4
5
6
7
mysql>SELECTGender,SUM(Age)FROMstudents_tbGROUPBYGenderORDERBYSUM(Age)DESC;

+--------+----------+

|Gender|SUM(Age)|

+--------+----------+

|M|138|

|F|119|

+--------+----------+


查看students_tb表中男女生各是多少:

1
2
3
4
5
6
7
mysql>SELECTGender,COUNT(Name)FROMstudents_tbGROUPBYGender;

+--------+-------------+

|Gender|COUNT(Name)|

+--------+-------------+

|M|5|

|F|4|

+--------+-------------+


6.2、多表组合查询

6.2.1、联结查询(交叉联结,内联结,外联结(左外联结、右外联结))

a)、交叉联结(返回笛卡尔集)

关键字:CROSSJOIN

1
2
mysql>SELECT*FROMstudents_tbCROSSJOINclasses_tb;

#结果略,类似数学里的多项式相乘,这种对服务器的开销特别大,极少使用。


b)、自然联结:让两张表的某个相同字段进行等值关系联结,是左右外联结的交集

关键字:NATURAL...JOIN

1
2
3
4
5
6
7
8
9
10
11
12
mysql>SELECT*FROMstudents_tbNATURALJOINclasses_tb;

+---------+-----------+--------+------+--------+--------+-----------+

|ClassID|StudentID|Name|Age|Gender|Class|TeacherID|

+---------+-----------+--------+------+--------+--------+-----------+

|1|1|Tom|17|M|class1|5|

|3|2|Jack|18|M|class3|5|

|3|12|张三|47|M|class3|5|

|4|4|Jimima|15|F|class4|2|

|6|3|Lucy|21|F|class6|1|

|6|10|Cora|25|F|class6|1|

+---------+-----------+--------+------+--------+--------+-----------+

注意:在表students_tb中有些有的ClassID,而在classed_tb中没有相对应的值,采用内联结里是不显示出来的。


显示学生的信息,所在的班级也要显示出来:

1
2
3
4
5
6
7
8
9
10
11
mysql>SELECT*FROMstudents_tb,classes_tbWHEREstudents_tb.ClassID=classes_tb.ClassID;
#其实也是交叉联结过虑后的结果

+-----------+--------+------+--------+---------+---------+--------+-----------+

|StudentID|Name|Age|Gender|ClassID|ClassID|Class|TeacherID|

+-----------+--------+------+--------+---------+---------+--------+-----------+

|1|Tom|17|M|1|1|class1|5|

|2|Jack|18|M|3|3|class3|5|

|9|张三|47|M|3|3|class3|5|

|4|Jimima|15|F|4|4|class4|2|

|3|Lucy|21|F|6|6|class6|1|

|7|Cora|25|F|6|6|class6|1|

+-----------+--------+------+--------+---------+---------+--------+-----------+


c)、外联结

左外联结(语法:左表LEFTJOIN右表ON条件)

显示各个同学是哪个班级的,如果此同学还没有给定班级,则留空:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql>SELECT*FROMstudents_tbLEFTJOINclasses_tbONstudents_tb.ClassID=classes_tb.ClassID;

+-----------+--------+------+--------+---------+---------+--------+-----------+

|StudentID|Name|Age|Gender|ClassID|ClassID|Class|TeacherID|

+-----------+--------+------+--------+---------+---------+--------+-----------+

|1|Tom|17|M|1|1|class1|5|

|2|Jack|18|M|3|3|class3|5|

|3|Lucy|21|F|6|6|class6|1|

|4|Jimima|15|F|4|4|class4|2|

|5|Jimmy|30|M|9|NULL|NULL|NULL|

|6|Jim|26|M|7|NULL|NULL|NULL|

|7|Cora|25|F|6|6|class6|1|

|8|Echo|58|F|7|NULL|NULL|NULL|

|9|张三|47|M|3|3|class3|5|

+-----------+--------+------+--------+---------+---------+--------+-----------+


右外联结(语法:左表RIGHTJION右表ON条件)

显示各个班级有哪些同学,如果这个班级没有同学就留空:

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql>SELECT*FROMstudents_tbRIGHTJOINclasses_tbONstudents_tb.ClassID=classes_tb.ClassID;

+-----------+--------+------+--------+---------+---------+--------+-----------+

|StudentID|Name|Age|Gender|ClassID|ClassID|Class|TeacherID|

+-----------+--------+------+--------+---------+---------+--------+-----------+

|1|Tom|17|M|1|1|class1|5|

|NULL|NULL|NULL|NULL|NULL|2|class2|2|

|2|Jack|18|M|3|3|class3|5|

|9|张三|47|M|3|3|class3|5|

|4|Jimima|15|F|4|4|class4|2|

|NULL|NULL|NULL|NULL|NULL|5|class5|4|

|3|Lucy|21|F|6|6|class6|1|

|7|Cora|25|F|6|6|class6|1|

+-----------+--------+------+--------+---------+---------+--------+-----------+


全外联结:

mysql无全外联结

6.2.2、联合查询:UNION

1
2
3
4
5
6
7
8
9
10
mysql>SELECTName,AgeFROMteacher_tbWHEREAge>40UNIONSELECTName,AgeFROMstudents_tbWHEREAge>30;

+-----------+------+

|Name|Age|

+-----------+------+

|Yinghui|50|

|Fengbing|46|

|Shunbin|68|

|Echo|58|

|张三|47|

+-----------+------+


查询同学所对应的负责老师:

1
2
3
4
5
6
7
8
9
10
11
mysql>SELECTstudents_tb.NameASstudent_name,teacher_tb.NameASteacher_nameFROMstudents_tb,classes_tb,teacher_tbWHEREstudents_tb.ClassID=classes_tb.ClassIDANDclasses_tb.TeacherID=teacher_tb.TeacherID;

+--------------+----------------+

|student_name|teacher_name|

+--------------+----------------+

|Tom|Fengbing|

|Jack|Fengbing|

|张三|Fengbing|

|Jimima|Zhangshanfeng|

|Lucy|Wangbaoqiang|

|Cora|Wangbaoqiang|

+--------------+----------------+


6.2.3、内联结:INNERJON...ON

语法:

表1AS别名1INNERJOIN表1AS别名2ON别名1.字段=别名2.字段

1
2
3
4
5
6
7
8
9
10
11
mysql>SELECT*FROMstudents_tbASsINNERJOINclasses_tbAScONs.ClassID=c.ClassID;

+-----------+--------+------+--------+---------+---------+--------+-----------+

|StudentID|Name|Age|Gender|ClassID|ClassID|Class|TeacherID|

+-----------+--------+------+--------+---------+---------+--------+-----------+

|1|Tom|17|M|1|1|class1|5|

|2|Jack|18|M|3|3|class3|5|

|12|张三|47|M|3|3|class3|5|

|4|Jimima|15|F|4|4|class4|2|

|3|Lucy|21|F|6|6|class6|1|

|10|Cora|25|F|6|6|class6|1|

+-----------+--------+------+--------+---------+---------+--------+-----------+


6.3、子查询

6.3.1、WHERE子查询

显示年龄大于平均年龄的学生:

1
2
3
4
5
6
7
8
mysql>SELECTName,AgeFROMstudents_tbWHEREAge>(SELECTAVG(Age)FROMstudents_tb);

+--------+------+

|Name|Age|

+--------+------+

|Jimmy|30|

|Echo|58|

|张三|47|

+--------+------+


查询学生表中给定来存在的班级的学生信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql>SELECT*FROMclasses_tb;

+---------+--------+-----------+

|ClassID|Class|TeacherID|

+---------+--------+-----------+

|1|class1|5|

|2|class2|2|

|3|class3|5|

|4|class4|2|

|5|class5|4|

|6|class6|1|

+---------+--------+-----------+

#只有6个班级

mysql>SELECTName,ClassIDFROMstudents_tbWHEREClassIDNOTIN(SELECTClassIDFROMclasses_tb);

+-------+---------+

|Name|ClassID|

+-------+---------+

|Jimmy|9|

|Jim|7|

|Echo|7|

+-------+---------+

#7和9这两个班级是不存在的


查询各个班级中同学年龄大于全校平均年龄的同学的个数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql>SELECTClassID,COUNT(Name)FROMstudents_tbWHEREAge>(SELECTAVG(Age)FROMstudents_tb)GROUPBYClassID;

+---------+-------------+

|ClassID|COUNT(Name)|

+---------+-------------+

|3|1|

|7|1|

|9|1|

+---------+-------------+

mysql>SELECTName,Age,ClassIDFROMstudents_tbWHEREAge>(SELECTAVG(Age)FROMstudents_tb);
#验证上边的结果

+--------+------+---------+

|Name|Age|ClassID|

+--------+------+---------+

|Jimmy|30|9|

|Echo|58|7|

|张三|47|3|

+--------+------+---------+


6.3.2、FROM子查询:

查询表中男性同学中年龄大于20的:

1
2
3
4
5
6
7
8
mysql>SELECT*FROM(SELECTName,Age,GenderFROMstudents_tbWHEREGender=
'M'
)ASSWHEREAge>20;

+--------+------+--------+

|Name|Age|Gender|

+--------+------+--------+

|Jimmy|30|M|

|Jim|26|M|

|张三|47|M|

+--------+------+--------+


mysql中对子查询优化很有限,建议不要使用子查询,可改为其他的简单查询或联合查询。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: