4. 数据表的基本操作

空~2022年8月26日
  • MySQL
大约 47 分钟

4. 数据表的基本操作

数据操纵语言

数据操纵语言(Data Manipulation Language,DML)包含了数据库数据的增、删、改、查操作,其中主要包括 INSERTDELETEUPDATESELECT 四条命令。

MySQL 运算符

四大类运算符:算数运算符、比较运算符、逻辑运算符、位操作运算符

算数运算符

+、减-、乘*、除/、求余(模运算,%

比较运算符

一个比较运算符的结果总是 1(true)、0(false)或者 null。比较运算符经常在 select 的查询条件子句中使用

符号描述备注
=等于
<>, !=不等于
>大于
<小于
<=小于等于
>=大于等于
BETWEEN AND在两值之间>=min&&<=max
NOT BETWEEN不在两值之间
IN在集合中
NOT IN不在集合中
<=>严格比较两个 NULL 值是否相等两个操作码均为 NULL 时,其所得值为 1;而当一个操作码为 NULL 时,其所得值为 0
LIKE模糊匹配
REGEXPRLIKE正则式匹配
IS NULL为空
IS NOT NULL不为空
LEAST在有两个或多个参数时,返回最小值
GREATEST在有两个或多个参数时,返回最大值

比较运算符比较数字时,将数字作为浮点值比较,比较字符串时不区分大小写(除非使用 BINARY 关键字)。MySQL 会自动将字符串和数字进行互相转换,方便比较。

BINARY 关键字的使用:

示例:

SELECT 'Apple' = 'apple' , BINARY 'Apple' = 'apple';

结果

202208261345490

  1. 等于运算符=在比较数值时的规则:

    • 若有一个或两个操作数为 NULL,则比较运算的结果为 NULL
    • 若两个操作数都是字符串,则按照字符串进行比较。
    • 若两个操作数均为整数,则按照整数进行比较。
    • 若一个操作数为字符串,另一个操作数为数字,则 MySQL 可以自动将字符串转换为数字。
  2. <=>,安全的等于运算符,与=操作符执行相同的操作,不过<=>可以用来判断 null 值。

    示例:

    SELECT null = null, null = 0, null <=> null, null <=> 0;
    

    结果

    202208261426608

    <<=>>=运算符,这些运算符不能用于空值的判断

  3. LIKE 运算符,用来匹配字符串。

    LIKE 运算符在进行匹配时可以使用下面两种通配符:

    • %,匹配任何数目的字符,包括 0 个字符。
    • -,只能匹配 1 个字符。
  4. REGEXP 运算符,用来匹配字符串。

    REGEXP 运算符在进行匹配时可以使用下面几种通配符:

    • ^,匹配以该字符后面的字符开头的字符串。
    • $,匹配以该字符后面的字符结尾的字符串。
    • .,匹配任意单个字符。
    • [...],匹配在括号内的任何字符。
    • [abc],匹配abc[a-z]匹配任何字母,[0-9]匹配任何数字
    • [\^...],匹配不以括号内的任何字符开头的字符串。
    • *,匹配 0 个或多个在它前面的字符。

逻辑运算符

运算符作用
NOT 或者 !逻辑非
AND 或者 &&逻辑与
OR 和 ||逻辑或
XOR逻辑异或
  1. 逻辑非运算(NOT 或者 !

    NOT!都是逻辑非运算符,返回和操作数相反的结果,具体语法规则为:

    • 当操作数为 0(假)时,返回值为 1;

    • 当操作数为非零值时,返回值为 0;

    • 当操作数为 NULL 时,返回值为 NULL

    NOT 的优先级低于 +,因此 NOT 1+1 相当于 NOT(1+1),先计算 1+1,然后再进行 NOT 运算,由于操作数不为 0,因此 NOT 1+1 的结果是 0;

    相反,! 的优先级别要高于 +,因此 ! 1+1 相当于 (!1)+1,先计算 !1 结果为 0,再加 1,最后结果为 1。

  2. 逻辑与运算符(AND 或者 &&)

    AND&& 都是逻辑与运算符,具体语法规则为:

    • 当所有操作数都为非零值并且不为 NULL 时,返回值为 1;

    • 当一个或多个操作数为 0 时,返回值为 0;

    • 操作数中有任何一个为 NULL 时,返回值为 NULL

  3. 逻辑或运算符(OR 或者 ||

    OR|| 都是逻辑或运算符,具体语法规则为:

    • 当两个操作数都为非 NULL 值时,如果有任意一个操作数为非零值,则返回值为 1,否则结果为 0;
    • 当有一个操作数为 NULL 时,如果另一个操作数为非零值,则返回值为 1,否则结果为 NULL
    • 假如两个操作数均为 NULL 时,则返回值为 NULL
  4. 异或运算(XOR 运算符)

    XOR 表示逻辑异或,具体语法规则为:

    • 当任意一个操作数为 NULL 时,返回值为 NULL
    • 对于非 NULL 的操作数,如果两个操作数都是非 0 值或者都是 0 值,则返回值为 0;
    • 如果一个为 0 值,另一个为非 0 值,返回值为 1。
  5. 运算符的优先级

    优先级由低到高排列运算符
    1=(赋值运算)、:=
    2II、OR
    3XOR
    4&&、AND
    5NOT
    6BETWEEN、CASE、WHEN、THEN、ELSE
    7=(比较运算)、<=>、>=、>、<=、<、<>、!=、 IS、LIKE、REGEXP、IN
    8|
    9&
    10<<、>>
    11-(减号)、+
    12*、/、%
    13^
    14-(负号)、〜(位反转)
    15!

    在无法确定优先级的情况下,可以使用圆括号()来改变优先级,并且这样会使计算过程更加清晰。

MySQL 中的转义字符

在 MySQL 中,除了常见的字符之外,我们还会遇到一些特殊的字符,如换行符、回车符等。这些符号无法用字符来表示,因此需要使用某些特殊的字符来表示特殊的含义,这些字符就是转义字符。

转义字符一般以反斜杠符号\开头,用来说明后面的字符不是字符本身的含义,而是表示其它的含义。MySQL 中常见的转义字符如下表所示。

转义字符转义后的字符
\"双引号(")
\'单引号(')
\\反斜线(\)
\n换行符
\r回车符
\t制表符
\0ASCII 0(NUL)
\b退格符

转义字符区分大小写,例如:\b 解释为退格,但 \B 解释为 B

提示

  • 字符串的内容包含单引号'时,可以用单引号'或反斜杠\来转义。
  • 字符串的内容包含双引号"时,可以用双引号"或反斜杠\来转义。
  • 一个字符串用双引号"引用时,该字符串中的单引号'不需要特殊对待,且不必被重复转义。同理,一个字符串用单引号'引用时,该字符串中的双引号"不需要特殊对待,且不必被重复转义。

示例:

SELECT 'Hello', '" Hello "','"" Hello ""',' Hel''lo', '\\' Hello ';

结果

202208261407440

插入表数据

数据库与表创建成功以后,需要向数据库的表中插入数据。在 MySQL 中可以使用 INSERT 语句向数据库已有的表中插入一行或者多行元组数据。

基本语法

INSERT 语句有两种语法形式,分别是 INSERT…VALUES 语句和 INSERT…SET 语句。

INSERT…VALUES 语句

INSERT INTO <表名> [<列名 1> [ , … <列名 n>] ] VALUES (值 1) [… , (值 n) ];

语法说明如下:

  • <表名>:指定被操作的表名。
  • <列名>:指定需要插入数据的列名。若向表中的所有列插入数据,则全部的列名均可以省略,直接采用 INSERT <表名>VALUES(…) 即可,但值的顺序必须和表中字段定义的顺序相同。
  • VALUESVALUE 子句:该子句包含要插入的数据清单。数据清单中数据的顺序要和列的顺序相对应。

INSERT…SET 语句

INSERT INTO <表名> SET <列名 1> = <值 1>, <列名 2> = <值 2>, …

此语句用于直接给表中的某些列指定对应的列值,即要插入的数据的列名在 SET 子句中指定。

INSERT 语句的两种形式可以看出:

  • 使用 INSERT…VALUES 语句可以向表中插入一行数据,也可以插入多行数据;
  • 使用 INSERT…SET 语句可以指定插入行中每列的值,也可以指定部分列的值;
  • INSERT…SELECT 语句向表中插入其他表的数据。
  • 采用 INSERT…SET 语句可以向表中插入部分列的值,这种方式更为灵活;
  • INSERT…VALUES 语句可以一次插入多条数据。

向表中的全部字段添加值

向表中所有字段插入值的方法有两种:一种是指定所有字段名;另一种是完全不指定字段名。不指定字段名时不要按照表定义的顺序插入,只要保证值的顺序与列字段的顺序相同就可以。

向表中指定字段添加值

为表的指定字段插入数据,是在 INSERT 语句中只向部分字段中插入值,而其他字段的值为表定义时的默认值。

要保证每个插入值的类型和对应的数据类型匹配,如果类型不同,将无法插入,并且 MySQL 会产生错误。

修改表数据

在 MySQL 中,可以使用 UPDATE 语句来修改、更新一个或多个表的数据。

UPDATE 语句的基本语法

使用 UPDATE 语句修改单个表,语法格式为:

UPDATE <表名> SET 字段 1=值 1 [,字段 2=值 2… ] [WHERE 子句 ] [ORDER BY 子句] [LIMIT 子句];

语法说明如下:

  • <表名>:用于指定要更新的表名称。

  • SET 子句:用于指定表中要修改的列名及其列值。其中,每个指定的列值可以是表达式,也可以是该列对应的默认值。如果指定的是默认值,可用关键字 DEFAULT 表示列值。

  • WHERE 子句:可选项。用于限定表中要修改的行。若不指定,则修改表中所有的行。

  • ORDER BY 子句:可选项。用于限定表中的行被修改的次序。

  • LIMIT 子句:可选项。用于限定被修改的行数。

    提示

    修改一行数据的多个列值时,SET 子句的每个值用逗号分开即可。

    保证 UPDATE 以 WHERE 子句结束,通过 WHERE 子句指定被更新的记录所需要满足的条件,如果忽略 WHERE 子句,MySQL 将更新表中所有的行。

删除表数据

使用 DELETE 语句从单个表中删除数据,语法格式为:

DELETE FROM <表名> [WHERE 子句] [ORDER BY 子句] [LIMIT 子句]

语法说明如下:

  • <表名>:指定要删除数据的表名。

  • ORDER BY 子句:可选项。表示删除时,表中各行将按照子句中指定的顺序进行删除。

  • WHERE 子句:可选项。表示为删除操作限定删除条件,若省略该子句,则代表删除该表中的所有行。

  • LIMIT 子句:可选项。用于告知服务器在控制命令被返回到客户端前被删除行的最大值。

    提示

    在不使用 WHERE 条件的时候,将删除所有数据。

    如果想删除表中所有记录,还可以使用 truncate table 语句,truncate 将直接删除原来的表并创建一个新的表,truncate 是直接删除表而不是逐条删除记录,因此执行速度比 delete 快。

    语法格式:

    TRUNCATE TABLE <表名>

数据表的查询

在 MySQL 中,可以使用 SELECT 语句来查询数据。查询数据是指从数据库中根据需求,使用不同的查询方式来获取不同的数据,是使用频率最高、最重要的操作。

SELECT 的语法格式如下:

SELECT {* | <字段列名>} [ FROM <表 1>, <表 2>… [WHERE <表达式> [GROUP BY <group by definition> [HAVING <expression> [{<operator> <expression>}…]] [ORDER BY <order by definition>] [LIMIT[<offset>,] <row count>] ]

其中,各条子句的含义如下:

  • {* | <字段列名>}包含星号通配符的字段列表,表示所要查询字段的名称。
  • <表 1>,<表 2>…,表 1 和表 2 表示查询数据的来源,可以是单个或多个。
  • WHERE <表达式>是可选项,如果选择该项,将限定查询数据必须满足该查询条件。
  • GROUP BY< 字段 >,该子句告诉 MySQL 如何显示查询出来的数据,并按照指定的字段分组。
  • [ORDER BY< 字段 >],该子句告诉 MySQL 按什么样的顺序显示查询出来的数据,可以进行的排序有升序(ASC)和降序(DESC),默认情况下是升序。
  • [LIMIT[<offset>,]<row count>],该子句告诉 MySQL 每次显示查询出来的数据条数。

简单查询

  1. 选择指定的字段

    最简单的查询语句是:SELECT 输出列表达式;

    例如:SELECT 1 + 2;

    202208261345525

  2. 查询表中所有字段

    查询所有字段是指查询表中所有字段的数据。MySQL 提供了以下 2 种方式查询表中的所有字段。

    • 使用*通配符查询所有字段
    • 列出表的所有字段
  3. 使用*查询表的所有字段

    SELECT 可以使用*查找表中所有字段的数据,语法格式如下:

    SELECT * FROM 表名;

    使用*查询时,只能按照数据表中字段的顺序进行排列,不能改变字段的排列顺序。

    提示

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

  4. 列出表的所有字段

    SELECT 关键字后面的字段名为需要查找的字段,因此可以将表中所有字段的名称跟在 SELECT 关键字后面。如果忘记了字段名称,可以使用 DESC 命令查看表的结构。
    有时,由于表的字段比较多,不一定能记得所有字段的名称,因此该方法很不方便,不建议使用。

  5. 查询表中指定的字段

    查询表中的某一个字段的语法格式为:

    SELECT < 列名 > FROM < 表名 >;

    使用 SELECT 声明可以获取多个字段下的数据,只需要在关键字 SELECT 后面指定要查找的字段名称,不同字段名称之间用逗号,分隔开,最后一个字段后面不需要加逗号,语法格式如下:

    SELECT <字段名 1>,<字段名 2>,…,<字段名 n> FROM <表名>;

  6. 为表指定别名

    当表名很长或者执行一些特殊查询的时候,为了方便操作,可以为表指定一个别名,用这个别名代替表原来的名称。

    为表指定别名的基本语法格式为:

    <表名> [AS] <别名>

    其中各子句的含义如下:

    • <表名>:数据库中存储的数据表的名称。

    • <别名>:查询时指定的表的新名称。

    • AS 关键字可以省略,省略后需要将表名和别名用空格隔开。

    提示

    表的别名不能与该数据库的其它表同名。字段的别名不能与该表的其它字段同名。在条件表达式中不能使用字段的别名,否则会出现“ERROR 1054 (42S22): Unknown column”这样的错误提示信息。

  7. 为字段指定别名

    在使用 SELECT 语句查询数据时,MySQL 会显示每个 SELECT 后面指定输出的字段。有时为了显示结果更加直观,我们可以为字段指定一个别名。

    为字段指定别名的基本语法格式为:

    <字段名> [AS] <别名>

    其中,各子句的语法含义如下:

    • <字段名>:为数据表中字段定义的名称。

    • <字段别名>:字段新的名称。

    • AS 关键字可以省略,省略后需要将字段名和别名用空格隔开。

    提示

    表别名只在执行查询时使用,并不在返回结果中显示。而字段定义别名之后,会返回给客户端显示,显示的字段为字段的别名。

  8. 替换查询结果中的数据

    有时对所查询的某些字段希望得到的是一个总体情况,而不是具体的数据,这时就可以将查询结果替换。

    要替换查询结果中的数据,则使用查询中的 case 表达式,其基本语法格式为:

    CASE

    WHEN 条件 1 THEN 表达式 1

    WHEN 条件 2 THEN 表达式 2

    ……

    ELSE 表达式 N

    END

    语法说明:

    case 表达式case 开始,end 结束。MySQL 从条件 1开始判断,条件 1成立,输出表达式 1,结束;若条件 1不成立,判断条件 2,若条件 2成立,输出表达式 2后结束;……如果条件都不成立,则输出表达式 N

    例如:

    查询所有学生的每一门成绩总体情况

    SELECT stuid, cid,
    CASE
    WHEN score >  60 && score < 70 THEN '及格'
    WHEN score >= 70 && score < 80 THEN '一般'
    WHEN score >= 80 && score < 90 THEN '良好'
    WHEN score >= 90 then '优秀'
    ELSE '不及格'
    END
    FROM score;
    

    202208261345688

  9. 计算字段值

    使用 SELECT 对字段进行查询时,在结果中可以输出对字段值计算后的值,即在 SELECT 子句中可以使用表达式作为结果

    例如:

    查询所有学生每门课程成绩的 90% 是多少

    SELECT stuid, cid, score * 0.9 FROM score;
    

    202208261345695

  10. 过滤重复数据

    在 MySQL 中使用 SELECT 语句执行简单的数据查询时,返回的是所有匹配的记录。如果表中的某些字段没有唯一性约束,那么这些字段就可能存在重复值。为了实现查询不重复的数据,MySQL 提供了 DISTINCT 关键字。

    DISTINCT 关键字的主要作用就是对数据表中一个或多个字段重复的数据进行过滤,只返回其中的一条数据给用户。

    DISTINCT 关键字的语法格式为:

    SELECT DISTINCT <字段名> FROM <表名>;

其中,字段名为需要消除重复记录的字段名称,多个字段时用逗号隔开。

使用 DISTINCT 关键字时需要注意以下几点:

  • DISTINCT 关键字只能在 SELECT 语句中使用。
  • 在对一个或多个字段去重时,DISTINCT 关键字必须在所有字段的最前面。
  • 如果 DISTINCT 关键字后有多个字段,则会对多个字段进行组合去重,也就是说,只有多个字段组合起来完全是一样的情况下才会被去重。

常用函数

MySQL 函数是 MySQL 数据库提供的内部函数,这些内部函数可以帮助用户更加方便地处理表中的数据。函数就像预定的公式一样存放在数据库里,每个用户都可以调用已经存在的函数来完成某些功能。

提示

函数就是输入值然后得到相应的输出结果,输入值称为参数(parameter),输出值称为返回值。

函数可以很方便的地实现业务逻辑的重用,并且 MySQL 数据库允许用户自己创建函数,以适应实际的业务操作。正确使用函数会让读者在编写 SQL 语句时起到事半功倍的效果。

MySQL 函数用来对数据表中的数据进行相应的处理,以便得到用户希望得到的数据,使 MySQL 数据库的功能更加强大。

下面将简单介绍 MySQL 中包含的几类函数,以及这几类函数的使用范围和作用。

MySQL 函数包括数学函数、字符串函数、日期和时间函数、条件判断函数、系统信息函数加密函数等。这些函数不仅能帮助用户做很多事情,比如字符串的处理、数值的运算、日期的运算等,还可以帮助开发人员编写出简单快捷的 SQL 语句。

SELECTINSERTUPDATEDELETE 语句及其子句(例如 WHEREORDER BYHAVING 等)中都可以使用 MySQL 函数。例如,数据表中的某个数据是负数,现在需要将这个数据显示为整数,这时就可以在 SELECT 语句中使用绝对值函数。

下面介绍这几类函数的使用范围。

  • 数学函数主要用于处理数字。这类函数包括绝对值函数、正弦函数、余弦函数和获得随机数的函数等。
  • 字符串函数主要用于处理字符串。其中包括字符串连接函数、字符串比较函数、将字符串的字母都变成小写或大写字母的函数和获取子串的函数等。
  • 日期和时间函数主要用于处理日期和时间。其中包括获取当前时间的函数、获取当前日期的函数、返回年份的函数和返回日期的函数等。
  • 条件判断函数主要用于在 SQL 语句中控制条件选择。其中包括 IF 语句、CASE 语句和 WHERE 语句等。
  • 系统信息函数主要用于获取 MySQL 数据库的系统信息。其中包括获取数据库名的函数、获取当前用户的函数和获取数据库版本的函数等。
  • 加密函数主要用于对字符串进行加密解密。其中包括字符串加密函数和字符串解密函数等。
  • 其他函数主要包括格式化函数和锁函数等。

数学函数

函数名称作 用
ABS求绝对值
SQRT求二次方根
MOD求余数
CEIL 和 CEILING两个函数功能相同,都是返回不小于参数的最小整数,即向上取整
FLOOR向下取整,返回值转化为一个 BIGINT
RAND生成一个 0~1 之间的随机数,传入整数参数是,用来产生重复序列
ROUND对所传参数进行四舍五入
SIGN返回参数的符号
POW 和 POWER两个函数的功能相同,都是所传参数的次方的结果值
SIN求正弦值
ASIN求反正弦值,与函数 SIN 互为反函数
COS求余弦值
ACOS求反余弦值,与函数 COS 互为反函数
TAN求正切值
ATAN求反正切值,与函数 TAN 互为反函数
COT求余切值

字符串函数

函数名称作 用
LENGTH计算字符串长度函数,返回字符串的字节长度
CONCAT合并字符串函数,返回结果为连接参数产生的字符串,参数可以使一个或多个
INSERT替换字符串函数
LOWER将字符串中的字母转换为小写
UPPER将字符串中的字母转换为大写
LEFT从左侧字截取符串,返回字符串左边的若干个字符
RIGHT从右侧字截取符串,返回字符串右边的若干个字符
TRIM删除字符串左右两侧的空格
REPLACE字符串替换函数,返回替换后的新字符串
SUBSTRING截取字符串,返回从指定位置开始的指定长度的字符换

日期和时间函数

函数名称作 用
CURDATE 和 CURRENT_DATE两个函数作用相同,返回当前系统的日期值
CURTIME 和 CURRENT_TIME两个函数作用相同,返回当前系统的时间值
NOW 和 SYSDATE两个函数作用相同,返回当前系统的日期和时间值
UNIX_TIMESTAMP获取 UNIX 时间戳函数,返回一个以 UNIX 时间戳为基础的无符号整数
FROM_UNIXTIME将 UNIX 时间戳转换为时间格式,与 UNIX_TIMESTAMP 互为反函数
MONTH获取指定日期中的月份
MONTHNAME获取指定日期中的月份英文名称
DAYNAME获取指定曰期对应的星期几的英文名称
DAYOFWEEK获取指定日期对应的一周的索引位置值
WEEK获取指定日期是一年中的第几周,返回值的范围是否为 0〜52 或 1〜53
DAYOFYEAR获取指定曰期是一年中的第几天,返回值范围是 1~366
DAYOFMONTH获取指定日期是一个月中是第几天,返回值范围是 1~31
YEAR获取年份,返回值范围是 1970〜2069
TIME_TO_SEC将时间参数转换为秒数
SEC_TO_TIME将秒数转换为时间,与 TIME_TO_SEC 互为反函数
DATE_ADD 和 ADDDATE两个函数功能相同,都是向日期添加指定的时间间隔
DATE_SUB 和 SUBDATE两个函数功能相同,都是向日期减去指定的时间间隔
ADDTIME时间加法运算,在原始时间上添加指定的时间
SUBTIME时间减法运算,在原始时间上减去指定的时间
DATEDIFF获取两个日期之间间隔,返回参数 1 减去参数 2 的值
DATE_FORMAT格式化指定的日期,根据参数返回指定格式的值
WEEKDAY获取指定日期在一周内的对应的工作日索引

MySQL 中 DATE_FORMAT(date,format)函数是根据 format 指定的格式显示 date 值。

DATE_FORMAT() 函数接受两个参数:

  • date:是要格式化的有效日期值
  • format:是由预定义的说明符组成的格式字符串,每个说明符前面都有一个百分比字符(%)。

主要的 format 格式如下表所示。

说明符说明
%a工作日的缩写名称(Sun~Sat)
%b月份的缩写名称(Jan…Dec)
%c月份,数字形式(0~12)
%D带有英语后缀的该月日期(0th, 2st, 3nd,…)
%d该月日期,数字形式(00~31)
%e该月日期,数字形式((0~31)
%f微秒(000000 …999999)
%H以 2 位数表示 24 小时(00~23)
%h, %I以 2 位数表示 12 小时(01~12)
%i分钟,数字形式(00~59)
%j—年中的天数(001~366)
%k以 24 小时(0~23)表示
%l以 12 小时(1~12)表示
%M月份名称(January~December)
%m月份,数字形式(00~12)
%p上午(AM) 或下午(PM)
%r时间,12 小时制(小时 (hh): 分钟 (mm) : 秒数 (ss) 后加 AM 或 PM)
%S, %s以 2 位数形式表示秒(00~59)
%T时间,24 小时制(小时 (hh): 分钟 (mm): 秒数 (ss))
%U周(00~53),其中周日为每周的第一天
%u周(00~53),其中周一为每周的第一天
%V周(01~53),其中周日为每周的第一天,和%X 同时使用
%v周(01~53),其中周一为每周的第一天,和%x 同时使用
%W星期标识(周日、周一、周二…周六)
%w—周中的每日(0= 周日…6= 周六)
%X该周的年份,其中周日为每周的第一天,数字形式,4 位数,和%V 同时使用
%x该周的年份,其中周一为每周的第一天,数字形式,4 位数,和%v 同时使用
%Y4 位数形式表示年份
%y2 位数形式表示年份
%%%一个文字字符

聚合函数

函数名称作 用
MAX查询指定列的最大值
MIN查询指定列的最小值
COUNT统计查询结果的行数
SUM求和,返回指定列的总和
AVG求平均值,返回指定列数据的平均值

流程控制函数

函数名称作 用
IF判断,流程控制
IFNULL判断是否为空
CASE搜索语句

MySQL IF 语句允许您根据表达式的某个条件或值结果来执行一组 SQL 语句。

要在 MySQL 中形成一个表达式,可以结合文字,变量,运算符,甚至函数来组合。表达式可以返回 TRUE,FALSENULL,这三个值之一。

语法结构如下:

IF(expr,v1,v2)

其中:表达式 expr 得到不同的结果,当 expr 为真是返回 v1 的值,否则返回 v2。

MySQL IFNULL 函数是 MySQL 控制流函数之一,它接受两个参数,如果不是 NULL,则返回第一个参数。否则,IFNULL 函数返回第二个参数。两个参数可以是文字值或表达式。

函数的语法:

IFNULL(v1,v2)

其中:如果 v1 不为 NULL,则 IFNULL 函数返回 v1; 否则返回 v2 的结果。

单表查询

在 MySQL 中,可以使用 SELECT 语句来查询数据。查询数据是指从数据库中根据需求,使用不同的查询方式来获取不同的数据,是使用频率最高、最重要的操作。

SELECT 的语法格式如下:

SELECT { * | <字段列名>} [FROM <表 1>, <表 2>… [WHERE <表达式> [GROUP BY <group by definition> [HAVING <expression> [{<operator> <expression>}…]] [ORDER BY <order by definition>] [LIMIT[<offset>,] <row count>] ]

其中,各条子句的含义如下:

  • {*|<字段列名>}包含星号通配符的字段列表,表示所要查询字段的名称。
  • <表 1>,<表 2>…,表 1 和表 2 表示查询数据的来源,可以是单个或多个。
  • WHERE <表达式>是可选项,如果选择该项,将限定查询数据必须满足该查询条件。
  • GROUP BY <字段>,该子句告诉 MySQL 如何显示查询出来的数据,并按照指定的字段分组。
  • [ORDER BY<字段>],该子句告诉 MySQL 按什么样的顺序显示查询出来的数据,可以进行的排序有升序(ASC)和降序(DESC),默认情况下是升序。
  • [LIMIT[<offset>,] <row count>],该子句告诉 MySQL 每次显示查询出来的数据条数。

条件查询数据

在 MySQL 中,如果需要有条件的从数据表中查询数据,可以使用 WHERE 关键字来指定查询条件。

使用 WHERE 关键字的语法格式如下:

WHERE 查询条件

查询条件可以是:

  • 带比较运算符和逻辑运算符的查询条件
  • BETWEEN AND 关键字的查询条件
  • IS NULL 关键字的查询条件
  • IN 关键字的查询条件
  • LIKE 关键字的查询条件
  1. 单一条件的查询语句

    单一条件指的是在 WHERE 关键字后只有一个查询条件。

  2. 多条件的查询语句

    WHERE 关键词后可以有多个查询条件,这样能够使查询结果更加精确。多个查询条件时用逻辑运算符 AND&&)、OR||)或 XOR 隔开。

    • AND:记录满足所有查询条件时,才会被查询出来。
    • OR:记录满足任意一个查询条件时,才会被查询出来。
    • XOR:记录满足其中一个条件,并且不满足另一个条件时,才会被查询出来。

    ORANDXOR 可以一起使用,但是在使用时要注意运算符的优先级。

    查询条件越多,查询出来的记录就会越少。因为,设置的条件越多,查询语句的限制就更多,能够满足所有条件的记录就更少。为了使查询出来的记录正是自己想要的,可以在 WHERE 语句中将查询条件设置的更加具体。

  3. 范围查询

    MySQL 提供了 BETWEEN AND 关键字,用来判断字段的数值是否在指定范围内。

    BETWEEN AND 需要两个参数,即范围的起始值和终止值。如果字段值在指定的范围内,则这些记录被返回。如果不在指定范围内,则不会被返回。

    使用 BETWEEN AND 的基本语法格式如下:

    [NOT] BETWEEN 取值 1 AND 取值 2

    其中:

    • NOT:可选参数,表示指定范围之外的值。如果字段值不满足指定范围内的值,则这些记录被返回。

    • 取值 1:表示范围的起始值。

    • 取值 2:表示范围的终止值。

    BETWEEN AND 和 NOT BETWEEN AND 关键字在查询指定范围内的记录时很有用。例如,查询学生的年龄段、出生日期,员工的工资水平等。

    在 MySQL 中,BETWEEN AND 能匹配指定范围内的所有值,包括起始值和终止值。

  4. 空值查询

    MySQL 提供了 IS NULL 关键字,用来判断字段的值是否为空值(NULL)。空值不同于 0,也不同于空字符串。

    如果字段的值是空值,则满足查询条件,该记录将被查询出来。如果字段的值不是空值,则不满足查询条件。

    使用 IS NULL 的基本语法格式如下:

    IS [NOT] NULL

    其中,NOT是可选参数,表示字段值不是空值时满足条件。

    提示

    IS NULL 是一个整体,不能将 IS 换成=。如果将 IS 换成=将不能查询出任何结果,数据库系统会出现Empty set(0.00 sec)这样的提示。

    同理,IS NOT NULL 中的 IS NOT 不能换成!=<>

    IS NOT NULL 表示查询字段值不为空的记录。

  5. INNOT IN 用法详解

    MySQL 中的 IN 运算符用来判断表达式的值是否位于给出的列表中;如果是,返回值为 1,否则返回值为 0。
    NOT IN 的作用和 IN 恰好相反,NOT IN 用来判断表达式的值是否不存在于给出的列表中;如果不是,返回值为 1,否则返回值为 0。
    INNOT IN 的语法格式如下:

    expr IN ( value1, value2, value3 ... valueN ) expr NOT IN ( value1, value2, value3 ... valueN )

    expr 表示要判断的表达式,value1, value2, value3 ... valueN 表示列表中的值。MySQL 会将 expr 的值和列表中的值逐一对比。

对空值 NULL 的处理

IN 运算符的两侧有一个为空值 NULL 时,如果找不到匹配项,则返回值为 NULL;如果找到了匹配项,则返回值为 1。

NOT IN 恰好相反,当 NOT IN 运算符的两侧有一个为空值 NULL 时,如果找不到匹配项,则返回值为 NULL;如果找到了匹配项,则返回值为 0。

模糊查询

在 MySQL 中,LIKE 关键字主要用于搜索匹配字段中的指定内容。其语法格式如下:

[NOT] LIKE '字符串'

其中:

  • NOT:可选参数,字段中的内容与指定的字符串不匹配时满足条件。

  • 字符串:指定用来匹配的字符串。“字符串”可以是一个很完整的字符串,也可以包含通配符。

    LIKE 关键字支持百分号%和下划线_通配符。

    通配符是一种特殊语句,主要用来模糊查询。当不知道真正字符或者懒得输入完整名称时,可以使用通配符来代替一个或多个真正的字符。

  1. 带有%通配符的查询

    %是 MySQL 中最常用的通配符,它能代表任何长度的字符串,字符串的长度可以为 0。例如,a%b 表示以字母 a 开头,以字母 b 结尾的任意长度的字符串。该字符串可以代表 ab、acb、accb、accrb 等字符串。

    提示

    匹配的字符串必须加单引号或双引号。

  2. 带有_通配符的查询

    _只能代表单个字符,字符的长度不能为 0。例如,a_b 可以代表 acb、adb、aub 等字符串。

  3. LIKE 区分大小写

    默认情况下,LIKE 关键字匹配字符的时候是不区分大小写的。如果需要区分大小写,可以加入 BINARY 关键字。

NOT LIKE 表示字符串不匹配时满足条件。

使用通配符的注意事项和技巧

下面是使用通配符的一些注意事项:

  • 注意大小写。MySQL 默认是不区分大小写的。如果区分大小写,像Tom这样的数据就不能被"t%"所匹配到。

  • 注意尾部空格,尾部空格会干扰通配符的匹配。例如,"T% "就不能匹配到Tom

  • 注意 NULL%通配符可以到匹配任意字符,但是不能匹配 NULL。也就是说 %匹配不到 tb_students_info 数据表中值为 NULL 的记录。

下面是一些使用通配符要记住的技巧。

  • 不要过度使用通配符,如果其它操作符能达到相同的目的,应该使用其它操作符。因为 MySQL 对通配符的处理一般会比其他操作符花费更长的时间。

  • 在确定使用通配符后,除非绝对有必要,否则不要把它们用在字符串的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。

  • 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。

如果查询内容中包含通配符,可以使用\转义符。

对查询结果排序

通过条件查询语句可以查询到符合用户需求的数据,但是查询到的数据一般都是按照数据最初被添加到表中的顺序来显示。为了使查询结果的顺序满足用户的要求,MySQL 提供了 ORDER BY 关键字来对查询结果进行排序。

在实际应用中经常需要对查询结果进行排序,比如,在网上购物时,可以将商品按照价格进行排序;在医院的挂号系统中,可以按照挂号的先后顺序进行排序等。

ORDER BY 关键字主要用来将查询结果中的数据按照一定的顺序进行排序。其语法格式如下:

ORDER BY <字段名> [ASC|DESC]

语法说明如下。

  • <字段名>:表示需要排序的字段名称,多个字段时用逗号隔开。
  • ASC|DESCASC 表示字段按升序排序;DESC 表示字段按降序排序。其中 ASC 为默认值。

使用 ORDER BY 关键字应该注意以下几个方面:

  • ORDER BY 关键字后可以跟子查询。
  • 当排序的字段中存在空值时,ORDER BY 会将该空值作为最小值来对待。
  • ORDER BY 指定多个字段进行排序时,MySQL 会按照字段的顺序从左到右依次进行排序。

提示

在对多个字段进行排序时,排序的第一个字段必须有相同的值,才会对第二个字段进行排序。如果第一个字段数据中所有的值都是唯一的,MySQL 将不再对第二个字段进行排序。

当使用 ROLLUP 时,不能同时使用 ORDER BY 子句进行结果排序。

分组查询

在 MySQL 中,GROUP BY 关键字可以根据一个或多个字段对查询结果进行分组。

使用 GROUP BY 关键字的语法格式如下:

GROUP BY <字段名>

其中,字段名表示需要分组的字段名称,多个字段时用逗号隔开。

  1. GROUP BY 单独使用

    单独使用 GROUP BY 关键字时,查询结果会只显示每个分组的第一条记录。

  2. GROUP BYGROUP_CONCAT()

    GROUP BY 关键字可以和 GROUP_CONCAT() 函数一起使用。GROUP_CONCAT() 函数会把每个分组的字段值都显示出来。

示例:

下面根据 student 表中的 stusex 字段进行分组查询,使用 GROUP_CONCAT() 函数将每个分组的 stuname 字段的值都显示出来。SQL 语句和运行结果如下:

SELECT stusex, *GROUP_CONCAT(*stuname*)
*FROM student
GROUP BY stusex;

202208261425827

  1. GROUP BY 与聚合函数

    在数据统计时,GROUP BY 关键字经常和聚合函数一起使用。

    聚合函数包括 COUNT()SUM()AVG()MAX()MIN()。其中,COUNT() 用来统计记录的条数;SUM() 用来计算字段值的总和;AVG() 用来计算字段值的平均值;MAX() 用来查询字段的最大值;MIN() 用来查询字段的最小值。

  2. GROUP BYWITH ROLLUP

WITH POLLUP 关键字用来在所有记录的最后加上一条记录,这条记录是上面所有记录的总和,即统计记录数量。

示例:

下面根据 student 表中的 stusex 字段进行分组查询,并使用 WITH ROLLUP 显示记录的总和。

SELECT stusex, *GROUP_CONCAT(*stuname*)
*FROM student
GROUP BY stusex
WITH ROLLUP;

202208261345590

过滤分组

在 MySQL 中,可以使用 HAVING 关键字对分组后的数据进行过滤。

使用 HAVING 关键字的语法格式如下:

HAVING <查询条件>

HAVING 关键字和 WHERE 关键字都可以用来过滤数据,且 HAVING 支持 WHERE 关键字中所有的操作符和语法。

但是 WHEREHAVING 关键字也存在以下几点差异:

  • 一般情况下,WHERE 用于过滤数据行,而 HAVING 用于过滤分组。
  • WHERE 查询条件中不可以使用聚合函数,而 HAVING 查询条件中可以使用聚合函数。
  • WHERE 在数据分组前进行过滤,而 HAVING 在数据分组后进行过滤 。
  • WHERE 针对数据库文件进行过滤,而 HAVING 针对查询结果进行过滤。也就是说,WHERE 根据数据表中的字段直接进行过滤,而 HAVING 是根据前面已经查询出的字段进行过滤。
  • WHERE 查询条件中不可以使用字段别名,而 HAVING 查询条件中可以使用字段别名。

限制查询结果的条数

当数据表中有上万条数据时,一次性查询出表中的全部数据会降低数据返回的速度,同时给数据库服务器造成很大的压力。这时就可以用 LIMIT 关键字来限制查询结果返回的条数。

LIMIT 是 MySQL 中的一个特殊关键字,用于指定查询结果从哪条记录开始显示,一共显示多少条记录。

LIMIT 关键字有 3 种使用方式,即指定初始位置、不指定初始位置以及与 OFFSET 组合使用。

  1. 指定初始位置

    LIMIT 关键字可以指定查询结果从哪条记录开始显示,显示多少条记录。

    LIMIT 指定初始位置的基本语法格式如下:

    LIMIT 初始位置,记录数

    其中,初始位置表示从哪条记录开始显示;记录数表示显示记录的条数。第一条记录的位置是 0,第二条记录的位置是 1。后面的记录依次类推。

    提示

    LIMIT 后的两个参数必须都是正整数。

    分页公式:

    每页显示 pagsize 条记录:

    第 pageno 页:(pageno - 1) * pagesize,pagesize

    pagesize:每页显示多少条记录

    pageno:第几页

  2. 不指定初始位置

    LIMIT 关键字不指定初始位置时,记录从第一条记录开始显示。显示记录的条数由 LIMIT 关键字指定。

    LIMIT 不指定初始位置的基本语法格式如下:

    LIMIT 记录数

    其中,记录数表示显示记录的条数。如果记录数的值小于查询结果的总数,则会从第一条记录开始,显示指定条数的记录。如果记录数的值大于查询结果的总数,则会直接显示查询出来的所有记录。

带一个参数的 LIMIT 指定从查询结果的首行开始,唯一的参数表示返回的行数,即LIMIT nLIMIT 0,n返回结果相同。带两个参数的 LIMIT 可返回从任何位置开始指定行数的数据。

LIMIT 和 OFFSET 组合使用

LIMIT 可以和 OFFSET 组合使用,语法格式如下:

LIMIT 记录数 OFFSET 初始位置

参数和 LIMIT 语法中参数含义相同,初始位置指定从哪条记录开始显示;记录数表示显示记录的条数。

使用聚合函数查询

有时候不需要返回实际表中的数据,而只是对数据进行总结。

常用的聚合函数有:计数 COUNT()、求平均值 AVG()、求最大值 MAX()、求最小值 MIN()、求和 SUM()

  1. COUNT 函数:统计查询结果的行数

    MySQL COUNT() 函数统计数据表中包含的记录行的总数,或者根据查询结果返回列中包含的数据行数,使用方法有以下两种:

    • COUNT(*) 计算表中总的行数,无论某列有数值或者为空值。
    • COUNT(字段名)计算指定列下总的行数,计算时将忽略空值的行。
  2. SUM 函数:求和

    MySQL SUM()是一个求总和的函数,返回指定列值的总和。

    SUM() 函数是如何工作的?

    • 如果在没有返回匹配行 SELECT 语句中使用 SUM 函数,则 SUM 函数返回 NULL,而不是 0。
    • DISTINCT 运算符允许计算集合中的不同值。
    • SUM 函数忽略计算中的 NULL 值。
  3. AVG 函数:求平均值

    MySQL AVG()函数通过计算返回的行数和每一行数据的和,求得指定列数据的平均值。

    提示

    使用 AVG() 函数时,参数为要计算的列名称,若要得到多个列的平均值,则需要在每一列都使用 AVG() 函数。

  4. MAX 函数:查询指定列的最大值

    MySQL MAX()函数是用来返回指定列中的最大值。

    MAX() 函数不仅适用于查找数值类型,也可应用于字符类型 MAX() 函数可以对字母进行大小判断,并返回最大的字符或者字符串值。

    提示

    MAX()函数还可以返回任意列中的最大值,包括返回字符类型的最大值。在对字符类型的数据进行比较时,按照字符的 ASCII 码值大小进行比较,从 a ~ z,a 的 ASCII 码最小,z 的最大。在比较时,先比较第一个字符,如果相等,继续比较下一个字符,一直到两个字符不相等或者字符结束为止。例如,b 与 t 比较时,t 为最大值;bcd 与 bca 比较时,bcd 为最大值。

  5. MIN 函数:查询指定列的最小值

    MySQL MIN()函数是用来返回查询列中的最小值。

    提示

    MIN() 函数与 MAX() 函数类似,不仅适用于查找数值类型,也可应用于字符类型。

连接查询

INNER JOIN:内连接

内连接(INNER JOIN)主要通过设置连接条件的方式,来移除查询结果中某些数据行的交叉连接。简单来说,就是利用条件表达式来消除交叉连接的某些数据行。

内连接使用 INNER JOIN 关键字连接两张表,并使用 ON 子句来设置连接条件。如果没有连接条件,INNER JOINCROSS JOIN(交叉连接)在语法上是等同的,两者可以互换。

内连接的语法格式如下:

SELECT <字段名> FROM <表 1> INNER JOIN <表 2> [ON 子句]

语法说明如下。

  • <字段名>`:需要查询的字段名称。

  • <表 1><表 2>:需要内连接的表名。

  • INNER JOIN :内连接中可以省略 INNER 关键字,只用关键字 JOIN。

  • ON 子句:用来设置内连接的连接条件。

    INNER JOIN 也可以使用 WHERE 子句指定连接条件,但是 INNER JOIN ... ON 语法是官方的标准写法,而且 WHERE 子句在某些时候会影响查询的性能。

多个表内连接时,在 FROM 后连续使用 INNER JOINJOIN 即可。

提示

当对多个表进行查询时,要在 SELECT 语句后面指定字段是来源于哪一张表。因此,在多表查询时,SELECT 语句后面的写法是表名.列名。另外,如果表名非常长的话,也可以给表设置别名,这样就可以直接在 SELECT 语句后面写上表的别名.列名

外连接

外连接可以分为左外连接和右外连接,下面根据实例分别介绍左外连接和右外连接。

  • 左连接

    左外连接又称为左连接,使用 LEFT OUTER JOIN 关键字连接两个表,并使用 ON 子句来设置连接条件。

    左连接的语法格式如下:

    SELECT <字段名> FROM <表 1> LEFT OUTER JOIN <表 2> <ON 子句>

    语法说明如下。

    • <字段名:需要查询的字段名称。

    • <表 1><表 2>:需要左连接的表名。

    • LEFT OUTER JOIN:左连接中可以省略 OUTER 关键字,只使用关键字 LEFT JOIN。

    • ON 子句:用来设置左连接的连接条件,不能省略。

    上述语法中,“表 1”为基表,“表 2”为参考表。左连接查询时,可以查询出“表 1”中的所有记录和“表 2”中匹配连接条件的记录。如果“表 1”的某行在“表 2”中没有匹配行,那么在返回结果中,“表 2”的字段值均为空值(NULL)。

  • 右连接

    右外连接又称为右连接,右连接是左连接的反向连接。使用 RIGHT OUTER JOIN 关键字连接两个表,并使用 ON 子句来设置连接条件。

    右连接的语法格式如下:

    SELECT <字段名> FROM <表 1> RIGHT OUTER JOIN <表 2> <ON 子句>

    语法说明如下。

    • <字段名>:需要查询的字段名称。

    • <表 1><表 2>:需要右连接的表名。

    • RIGHT OUTER JOIN:右连接中可以省略 OUTER 关键字,只使用关键字 RIGHT JOIN

    • ON 子句:用来设置右连接的连接条件,不能省略。

    与左连接相反,右连接以“表 2”为基表,“表 1”为参考表。右连接查询时,可以查询出“表 2”中的所有记录和“表 1”中匹配连接条件的记录。如果“表 2”的某行在“表 1”中没有匹配行,那么在返回结果中,“表 1”的字段值均为空值(NULL)。

多个表左/右连接时,在ON 子句后连续使用 LEFT/RIGHT OUTER JOINLEFT/RIGHT JOIN 即可。

使用外连接查询时,一定要分清需要查询的结果,是需要显示左表的全部记录还是右表的全部记录,然后选择相应的左连接和右连接。

交叉连接

交叉连接(CROSS JOIN)一般用来返回连接表的笛卡尔积。

交叉连接的语法格式如下:

SELECT <字段名> FROM <表 1> CROSS JOIN <表 2> [WHERE 子句]

SELECT <字段名> FROM <表 1>, <表 2> [WHERE 子句]

语法说明如下:

  • <字段名>:需要查询的字段名称。

  • <表 1><表 2>:需要交叉连接的表名。

  • WHERE 子句:用来设置交叉连接的查询条件。

    提示

    多个表交叉连接时,在 FROM 后连续使用 CROSS JOIN 或,即可。以上两种语法的返回结果是相同的,但是第一种语法才是官方建议的标准写法。

    当连接的表之间没有关系时,我们会省略掉 WHERE 子句,这时返回结果就是两个表的笛卡尔积,返回结果数量就是两个表的数据行相乘。需要注意的是,如果每个表有 1000 行,那么返回结果的数量就有 1000×1000 = 1000000 行,数据量是非常巨大的。

    如果在交叉连接时使用 WHERE 子句,MySQL 会先生成两个表的笛卡尔积,然后再选择满足 WHERE 条件的记录。因此,表的数量较多时,交叉连接会非常非常慢。一般情况下不建议使用交叉连接。

笛卡尔积

笛卡尔积(Cartesian product)是指两个集合 X 和 Y 的乘积。

例如,有 A 和 B 两个集合,它们的值如下:

A = {1,2} B = {3,4,5}

集合 A×B 和 B×A 的结果集分别表示为:

A×B={(1,3), (1,4), (1,5), (2,3), (2,4), (2,5) }; B×A={(3,1), (3,2), (4,1), (4,2), (5,1), (5,2) };

以上 A×B 和 B×A 的结果就叫做两个集合的笛卡尔积。

并且,从以上结果我们可以看出:

两个集合相乘,不满足交换率,即 A×B≠B×A。

A 集合和 B 集合的笛卡尔积是 A 集合的元素个数 × B 集合的元素个数。

多表查询遵循的算法就是以上提到的笛卡尔积,表与表之间的连接可以看成是在做乘法运算。在实际应用中,应避免使用笛卡尔积,因为笛卡尔积中容易存在大量的不合理数据,简单来说就是容易导致查询结果重复、混乱。

子查询

子查询是 MySQL 中比较常用的查询方法,通过子查询可以实现多表查询。子查询指将一个查询语句嵌套在另一个查询语句中。子查询可以在 SELECTUPDATEDELETE 语句中使用,而且可以进行多层嵌套。在实际开发时,子查询经常出现在 WHERE 子句中。

子查询在 WHERE 中的语法格式如下:

WHERE <表达式> <操作符> (子查询)

其中,操作符可以是比较运算符和 INNOT INEXISTSNOT EXISTS 等关键字。

  1. IN | NOT IN

    当表达式与子查询返回的结果集中的某个值相等时,返回 TRUE,否则返回 FALSE;若使用关键字 NOT,则返回值正好相反。

  2. EXISTS | NOT EXISTS

    用于判断子查询的结果集是否为空,若子查询的结果集不为空,返回 TRUE,否则返回 FALSE;若使用关键字 NOT,则返回的值正好相反。

    EXISTS 关键字可以和其它查询条件一起使用,条件表达式与 EXISTS 关键字之间用 ANDOR 连接。

  3. ANY | SOME | ALL

    ANYSOME 是同义词,表示满足其中任一条件,它们允许创建一个表达式对子查询的返回值列表进行比较,只要满足内存子查询中的任何一个比较条件,就返回一个结果作为外层查询条件。

    ALL 关键字与 ANYSOME 不同,使用 ALL 时,需要满足所有内层查询的条件。

习惯上,外层的 SELECT 查询称为父查询,圆括号中嵌入的查询称为子查询(子查询必须放在圆括号内)。MySQL 在处理上例的 SELECT 语句时,执行流程为:先执行子查询,再执行父查询。

拓展

子查询的功能也可以通过表连接完成,但是子查询会使 SQL 语句更容易阅读和编写。

子查询注意事项

在完成较复杂的数据查询时,经常会使用到子查询,编写子查询语句时,要注意如下事项。

子查询语句可以嵌套在 SQL 语句中任何表达式出现的位置。

SELECT 语句中,子查询可以被嵌套在 SELECT 语句的列、表和查询条件中,即 SELECT 子句,FROM 子句、WHERE 子句、GROUP BY 子句和 HAVING 子句。

嵌套在 SELECT 语句的 SELECT 子句中的子查询语法格式如下。

SELECT (子查询) FROM 表名;

提示:子查询结果为单行单列,但不必指定列别名。

嵌套在 SELECT 语句的 FROM 子句中的子查询语法格式如下。

SELECT * FROM (子查询) AS 表的别名;

提示

必须为表指定别名。一般返回多行多列数据记录,可以当作一张临时表。

只出现在子查询中而没有出现在父查询中的表不能包含在输出列中。

多层嵌套子查询的最终数据集只包含父查询(即最外层的查询)的 SELECT 子句中出现的字段,而子查询的输出结果通常会作为其外层子查询数据源或用于数据判断匹配。

常见错误如下:

SELECT * FROM (SELECT * FROM result);

这个子查询语句产生语法错误的原因在于主查询语句的 FROM 子句是一个子查询语句,因此应该为子查询结果集指定别名。正确代码如下。

SELECT * FROM (SELECT * FROM result) AS Temp;

合并查询结果

利用 UNION 关键字,可以给多出条 SELECT 语句,并将它们的结果组合成单个结果集。合并时,两个表对应的列数和数据类型必须相同。各个 SELECT 语句之间使用 UNIONUNION ALL 关键字分隔。UNION 不使用 ALL 关键字,执行时会删除重复记录,所有返回值都唯一;使用 ALL 关键字后不会删除重复行,也不会对结果进行自动排序。基本语法格式如下:

SELECT <字段名> FROM 表 1

UNION [ALL]

SELECT <字段名> FROM 表 2