掌握简单数据查询

数据查询是数据库中最常见的操作,SQL语言通过SELECT语句来实现查询。数据查询语句的语法结构如下:

SELECT 子句1 FROM 子句2
[WHERE 表达式1]
[GROUP BY 子句3 [HAVING 表达式2]]
[ORDER BY 子句4]
[UNION 运算符]
[LIMIT [M,]N]
[INTO OUTFILE 输出文件名]
单表无条件数据查询

语法格式:

SELECT [ALL|DISTINCT] <选项> [AS <显示列名>] [, <选项> [AS <显示列名>] [, ...]] 
FROM <表名|视图名> [LIMIT [M,]N]

说明:

  • ALL:表示输出所有记录,包括重复记录。默认值为ALL。
  • DISTINCT:表示在查询结果中去掉重复值
  • LIMIT N:返回查询结果集中的前N行。加[M,]表示从表的第M行开始,返回查询结果集中的N行。M从0开始,N的取值范围由表中的记录数决定。
  • 选项:查询结果集中的输出列。选项可为字段名、表达式或函数。用*表示表中的所有字段。若选项为表达式或函数,则系统自动给出输出的列名,不是原字段名,故用AS重命名。
  • 显示列名:在输出结果中,设置选项显示的列名。用引号定界或不定界。
  • 表名|视图名:表示查询的数据源,可以是表或视图。

查询结果的输出:

# 复制表
CREATE TABLE <新表名> SELECT 语句;

# 将查询结果输出到文本文件中
# INTO子句不能单独使用,它必须包含在SELECT语句中。
INTO OUTFILE '[文件路径]文本文件名' [FIELDS TERMINATED BY '分隔符']
使用WHERE子句实现条件查询

语法格式:

SELECT [ALL|DISTINCT] <选项> [AS<显示列名>] [,<选项> [AS<显示列名>] [,...]]
FROM <表名|视图名> WHERE <条件表达式>;

WHERE子句常用的运算符:

查询条件

运算符

比较运算符

=、<、>、<=、>=、<>、!=、!<、!>

范围运算符

BETWEEN AND、NOT BETWEEN AND

列表运算符

IN、NOT IN

字符匹配符

LIKE、NOT LIKE

空值

IS NULL、IS NOT NULL

逻辑运算符

AND、OR、NOT

在MySQL中,比较运算符几乎可以连接所有的数据类型。当连接的数据类型不是数字时,要用单引号'将数据引起来。在使用比较运算符时,运算符两边表达式的数据类型必须保持一致。比较字符串是不区分大小写的。

字符匹配符

在WHERE子句中使用字符匹配符LIKE或NOT LIKE可以比较表达式与字符串,从而实现对字符串的模糊查询。其语法格式如下:

WHERE 字段名 [NOT] LIKE '字符串' [ESCAPE '转义字符']

ESCAPE’转义字符’的作用是当用户要查询的字符串本身含有通配符时,可以使用该选项对通配符进行转义。

# 通配符及其说明
% -> 任意多个字符
M%:表示查询以M开头的任意字符串
%M:表示查询以M结尾的任意字符串
%m%:表示查询在任何位置包含字母m的所有字符串

_ -> 单个字符
_M:表示查询以任意一个字符开头,以M结尾的两位字符串
H_:表示查询以H开头,后面跟任意一个字符的两位字符串
正则表达式

正则表达式通常用来检索或替换符合某个模式的文本内容,根据指定的匹配模式匹配文本中符合要求的特殊字符串。在MySQL中使用REGEXP关键字指定正则表达式的字符匹配模式,其基本语法格式如下:

WHERE 字段名 REGEXP '操作符'
# 字符匹配选项列表
^ -> 匹配文本的开始字符
$ -> 匹配文本的结束字符
. -> 匹配任何单个字符
* -> 匹配零个或多个在它前面的字符
+ -> 匹配前面的字符1次或多次
<字符串> -> 匹配包含指定字符串的文本
[字符集合] -> 匹配字符集合中的任何一个字符
[^] -> 匹配不在括号中的任何字符
{字符串n,} -> 匹配前面的字符串至少n次
{字符串m,n} -> 匹配前面的字符串至少m次,至多n次。如果n为0,则m为可选参数。
列表运算符

在WHERE子句中,如果需要确定表达式的取值是否属于某一列表值之一时,可以使用关键字IN或NOT IN来限定查询条件。其语法格式如下:

WHERE 表达式 [NOT] IN 值列表

其中,NOT为可选项,当值不止一个时,需要将这些值用括号括起来,各列表值之间使用逗号(,)隔开。

使用常用聚集函数统计数据

MySQL的聚集函数是综合信息的统计函数,也称为聚集函数或集函数,包括计数、求最大值、求最小值、求平均值和求和等。聚集函数可作为列标识符出现在SELECT子句的目标列、HAVING子句的条件中或ORDER BY子句中。在SQL查询语句中,如果有GROUP BY子句,则语句中的函数为分组统计函数;否则,语句中的函数为全部结果集的统计函数。

# 聚集函数的具体用法及含义
COUNT   COUNT(*)                      统计元组个数
COUNT   COUNT([DISTINCT|ALL]<列名>)   统计一列中值的个数
SUM     SUM([DISTINCT|ALL]<列名>)     计算一列值的总和(此列必须为数值型)
AVG     AVG([DISTINCT|ALL]<列名>)     计算一列值的平均值(此列必须为数值型)
MAX     MAX([DISTINCT|ALL]<列名>)     求一列值的最大值
MIN     MIN([DISTINCT|ALL]<列名>)     求一列值的最小值

如果指定DISTINCT短语,则表示在计算时要取消指定列中的重复值。如果不指定DISTINCT短语或指定ALL短语(ALL为默认值),则表示不取消重复值。

分组筛选数据

使用GROUP BY子句可以将查询结果按照某一列或多列数据值分类,换句话说,就是对查询结果的信息进行归纳,以汇总相关数据。其语法格式如下:

[GROUP BY 列名清单 [HAVING 条件表达式]]

GROUP BY子句把查询结果集中的各行按列名清单分组。在这些列上,对应值都相同的记录分在同一组。若无HAVING子句,则各组分别输出;若有HAVING子句,则只有符合HAVING条件的组才输出。GROUP BY子句通常用于对某个子集或其中的一组数据,而不是对整个整体集中的数据进行合计运算。在SELECT语句的输出列中,只能包含两种目标列表达式,要么是聚集函数,要么是出现在GROUP BY子句中的分组字段,并且在GROUP BY子句中必须使用列的名称而不能使用AS子句中指定列的列名。

WHERE条件与HAVING条件的区别在于作用对象不同。
HAVING条件作用于结果组,选择满足条件的结果组;而WHERE条件作用于被查询的表,从中选择满足条件的记录。

对查询结果进行排序

用户可以利用ORDER BY子句对查询结果按照一个或多个字段进行升序(ASC)或降序(DESC)排序,默认值为升序。

[ORDER BY <列名1> [ASC|DESC] [,<列名2>[ASC|DESC]] [,...]]

掌握多表连接查询

多表连接查询是指查询同时涉及两个或两个以上的表,连接查询是关系数据库中最主要的数据查询,表与表之间的连接分为交叉连接(Cross Join)、内连接(Inner Join)、自连接(Self Join)、外连接(Outer Join)。外连接又分为3种,即左外连接(Left Join)、右外连接(Right Join)和全外连接(Full Join)。连接查询的类型可以在SELECT语句的FROM子句中指定,也可以在WHERE子句中指定。

交叉连接

交叉连接又称笛卡尔连接,是指两个表之间做笛卡尔积操作,得到结果集的行数是两个表的行数的乘积。交叉连接的一般格式如下:

SELECT [ALL|DISTINCT] [别名.]<选项1> [AS<显示列名>] [,[别名.]<选项2> [AS<显示列名>] [,...]]
FROM <表名1> [别名1], <表名2> [别名2];

此处为了简化,分别给两个表指定了别名。但是,一旦表名指定了别名,在该命令中,都必须用别名代替表名。

内连接

内连接的一般格式如下:

# 第一种格式:连接类型在WHERE子句中指定
SELECT [ALL|DISTINCT] [别名.]<选项1> [AS<显示列名>] [,[别名.]<选项2> [AS<显示列名>] [,...]]
FROM <表名1> [别名1], <表名2> [别名2] [,...]
WHERE <连接条件表达式> [AND <条件表达式>];

# 第二种格式:连接类型在FORM子句中指定
SELECT [ALL|DISTINCT] [别名.]<选项1> [AS<显示列名>] [,[别名.]<选项2> [AS<显示列名>] [,...]]
FROM <表名1> [别名1] INNER JOIN <表名2> [别名2] ON <连接条件表达式>
[WHERE <条件表达式>];

连接条件是指在连接查询中连接两个表的条件。连接条件表达式的一般格式如下:

[<表名1>]<别名1.列名> <比较运算符> [<表名2>]<别名2.列名>

说明:

  • FORM后可跟多个表名,表名与别名之间用空格间隔。
  • 当连接类型在WHERE子句中指定时,WHERE后一定要有连接条件表达式,即两个表的公共字段相等。
  • 若不定义别名,则表的别名默认为表名,定义别名后使用定义的别名。
  • 若在输出列或条件表达式中出现两个表的公共字段,则在公共字段名前必须加别名。

若在等值连接中把目标列中的重复字段去掉,则称为自然连接

自连接

连接操作不只是在不同的表之间进行,一张表内还可以进行自身连接操作,即将同一个表的不同行连接起来。自连接可以看作一张表的两个副本之间的连接。在自连接中,必须为表指定两个别名,使之在逻辑上成为两张表。自连接的一般格式如下:

SELECT [ALL|DISTINCT] [别名.]<选项1> [AS<显示列名>] [,[别名.]<选项2> [AS<显示列名>] [,...]]
FROM <表名1> [别名1], <表名1> [别名2] [,...]
WHERE <连接条件表达式> [AND <条件表达式>];
外连接

在自然连接中,只有在两个表中匹配的行才能在结果集中出现。而在外连接中可以只限制一个表,而对另外一个表不加限制(所有行都出现在结果集中)。外连接分为:

  • 左外连接:对连接条件中左边的表不加限制,即在结果集中保留连接表达式左边表中的非匹配记录。
  • 右外连接:对连接条件中右边的表不加限制,即在结果集中保留连接表达式右边表中的非匹配记录。
  • 全外连接:对两个表都不加限制,两个表中的所有行都会包括在结果集中。

外连接的一般格式如下:

SELECT [ALL|DISTINCT] [别名.]<选项1> [AS<显示列名>] [,[别名.]<选项2> [AS<显示列名>] [,...]]
FROM <表名1> LEFT|RIGHT|FULL [OUTER] JOIN <表名2> ON <表名1.列1>=<表名2.列2> ;

理解集合查询

MySQL只支持UNION(并操作)运算,对于INTERSECT(交操作)和EXCEPT(差操作)没有实现。

说明:

  • 在使用UNION操作符进行联合查询时,应保证每个联系查询语句的选择列表中具有相同数量的表达式。
  • 每个查询选择表达式应具有相同的数据类型,或者可以自动将它们转换为相同的数据类型。在自动转换时,数值类型系统将低精度的数据类型转换为高精度的数据类型。
  • 各语句中对应的结果集列出现的顺序必须相同。

数据更新

数据记录的插入
# 插入单条记录
INSERT INTO <表名>[(<列名清单>)] VALUES (<常量清单>);

# 插入多条记录
INSERT INTO <表名>[(<列名清单>)] VALUES (<常量清单1>),(<常量清单2>),...,(<常量清单n>);

# 插入子查询结果
INSERT INTO <表名>[(列名1,列名2,...)] <子查询语句>;

子查询不仅可以嵌套在SELECT语句中,用以构造主查询的条件,还可以嵌套在INSERT语句中,用以生成要插入的批量数据。

说明:

  • INSERT语句中的INTO可以省略
  • 如果某些属性列在表名后的列名表中没有出现,则新纪录在这些列上将取空值。但必须注意的是,在表定义时要说明NOT NULL的属性列不能为空值,否则系统会出现错误提示。
  • 如果没有指明任何列名,则新插入的记录必须在每个属性列上均有值。
  • 字符型数据必须使用“"”引起来
  • 常量的顺序必须和指定的列名顺序保持一致
  • 在把数据值从一列复制到另一列时,值所在列不必具有相同数据类型,只要插入目标表的值符合该表的数据限制即可。
数据记录的修改
# 修改表中已有数据的记录
UPDATE <表名> SET <列名1>=<表达式1> [,<列名2>=<表达式2>] [,...] [WHERE <条件表达式>];

如果省略WHERE子句,则表示要修改表中的所有记录。

数据记录的删除
DELETE FROM <表名> [WHERE <条件表达式>];

当无WHERE<条件表达式>项时,将删除<表名>中的所有记录。但是该表的表结构还在,只是没有了记录,是个空表而已。DELETE语句只能从一个基本表中删除记录。WHERE子句中的条件表达式可以嵌套,也可以是来自几个基本表的复合条件。

(最近更新:2019年09月03日)