查询数据指从数据库中获取所需要的数据。查询数据是数据库操作中最常用,也是最重要的操作。用户可能根据自己对数据的需求,使用不同的查询方式,可以获得不同的数据。MySQL中是使用select语句来实现数据的查询。
8.1 学生——课程数据库
8.2 基本查询语句
MySQL提供SELECT语句进行数据库的查询,该语句的一般格式为:
SELECT 属性列表
FROM 表名或视图名
[WHERE 条件表达式]
[GROUP BY 属性名 [HAVING 条件表达式]]
ORDER BY 属性名 [ASCIDESC]]
SELECT语句的含义是根据WHERE子句的条件表达式,从FROM子句指定的基表或视图中查找满足条件的记录。如果有GROUP BY子句,则将结果按照GROUP BY 子句后的属性进行分组,该属性值相等的记录分为一组,一般会在每组上是使用聚集函数进行统计。如果在GROUP BY 子句后带HAVING短语,则只有满足HAVING后面表达式的组才予输出。如果有DRDER BY子句,则会根据XRDER BY子句后面的属性进行升序或降序排序。
8.2.1 单表查询
单表查询是指从一张表中查询所需的数据。本节介绍从单表查询本分字段,所有字段、经过计算的值、满足条件的记录、查询空值、满足多条件的查询等内容。
8.2.2 查询表中的部分字段
在一般情况下,用户往往只对表中的部分字段感兴趣,可以通过SELECT子句指定哪些字段出现在结果中。不同字段之间用逗号分隔,最右一列后面不需要加逗号。
8.2.3 查询表中的所有字段
将表中所有的字段都查询出有两种方法:一种是在SELECT子句中将所有的字段都列出;另一种是将SELECT子句中的属性列表指定为‘*’,该符号代表所有列。
8.2.4 查询经过计算的值
8.2.5 查询表中的若干记录
- 清除取值重复的行
表中的记录没有重复,但查询后结果可能有相同的行,可以使用关键字DISTINCT来消除重复行。 - 查询表中满足条件的记录
在查询过程中,可能只需要查询表中特定的数据,即满足一定条件的数据,该要求可以通过WHERE子句来实现,即在WHERE子句中指出查询的条件。
(1)比较大小
下表为操作符列表,可用于WHERE子句中。
=,<> !=, >, <, >=, <=
返回true或false
(2)确定范围
如果查询条件为某字段在或不在某个范围,可以使用谓词BETWEEN…AND或NOT BETWEEN…AND,其中BETWEEN后面为下限,AND后面为上限。
(3)带IN关键字的查询
使用谓词IN来确定查找的字段属于指定的集合记录。与之相反,可以使用NOT IN来查找不属于指定集合的记录。
(4)带LIKE的字符匹配查询
可以使用“=”进行精确比较。谓词LIKE可以用来进行字符串的匹配,其语法格式如下:
[not]like‘<匹配串>’[escape’<换码字符>’]
该语法的含义是查找指定的字段值与匹配串相匹配的行的信息。匹配串可以是一个完整的字符串,也可以包含通配符“%”和“_”。
% ——匹配任何数目的字符,甚至包括零字符
_ ——只能匹配一个字符
转义字符的使用:
\%——匹配一个‘%’字符
_——匹配一个‘_’字符
要指定一个不同的转义字符,可使用ESCAPE语句。
(5)查询控制
在WHERE子句中可以使用 IS NULL来查询某字段内容为空的记录。
提示:IS NULL不能换成=NULL,如果换成=NULL,没有语法错误,但结果为空。
(6)多重条件查询
可以使用逻辑运算符AND或OR来连接多个查询条件。AND的优先级要高于OR,可以使用括号来改变优先级的顺序。
8.3 对查询结果进行排序
使用ORDER BY子句对查询结果进行排序,可以根据一列或多列对结果进行升序(ASC)和降序(DESC)的排列,缺省默认为升序。
提示:对于NULL值的处理,不同的DBMS采用不同的处理方式。MySQL中,升序时NULL值在最前方,降序时NULL排在最后。
8.4 统计函数和分组记录查询
- COUNG()函数
COUNG()函数有两种形式。一种为COUNG(*),参数为“*”,统计的是符合条件的行数;另外一种为COUNGt(列名),参数为列名,统计的是列中非空值的个数。这两种形式的参数前都可以加DISTINCT关键字消除重复。
提示:WHERE 子句中不能使用统计函数作为表达式
8.5 GROUP BY子句
MySQL使用GROUP BY将查询结果根据某一列或多列的值进行分组,值相等的为一组,分组的目的一般与统计有关。分组之前,统计的是整个查询结果,分组后统计的是每一个组,即每个组上的都会得到一个函数结果。
- 单子段分组
- 多字段分组
- GROUP BY 与 HAVING子句一起使用
如果查询结果只想输出满足某种指定条件的组,要使用HAVING子句对组进行筛选,得到符合条件的组的信息。 - GROUP BY子句与GROUP_CONCAT()函数一起使用
GROUP_CONCAT()函数返回一个字符串结果,该结果由分组中的值连接组合而成。 - GROUP BY子句使用ROLLUP
提示:返回结果的SELECT 子句字段中,这些字段要么包含在GROUP BY语句的后面,作为分组的依据;要么就要被包含在聚合中,作为函数的参数。
8.6 使用LIMIT限制查询结果的数量
如果查询结果有很多行,而用户想得到第一行或前几行,需要使用LIMIT关键字,其语法如下:
LIMIT[offset,]rowsrowsOFFSEToffset
LIMIT子句可以被用于强制SELECT语句返回指定的记录数。LIMIT接受一个或两个数字参数,参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是0(而不是1)。
8.7 连接查询
涉及两个或两个以上表的查询称之为连接查询。连接查询是关系数据库中最重要的查询类型。连接查询分为内连接查询、外连接查询和复合连接查询。连接查询要求参加连接的表必须要是有相同意义的字段。
- 内连接查询
连接查询中使用WHERE子句给出连接条件,格式:
Where [<表名 1.]<列名 1> <比较运算符>[<表名2.]<列名2>
这里的比较运算符通常是‘=’。
提示:定义表的别名以后,列的前缀要使用新定义的列的别名,否则出错。 - 外连接查询
在内连接查询中,只有满足连接条件的记录才能出现在查询结果中。但在实际应用中,希望不满足连接条件的记录出现在结果中,这时需要使用外连接查询。外链接分为左外连接、右外连接、完全外连接,但MySQL不支持完全外连接。
(1)left join(左连接):join左表中所有记录和右表中满足连接条件的记录信息。
(2)right join(右连接):join右表中所有记录和左表中满足连接条件的记录信息。 - 复合条件连接查询
WHERE子句中还可以跟多个连接条件,成为复合条件的连接。
连接查询除了可以两个表进行连接,还可以两个以上的表进行连接,称为多表连接。
8.8 子查询
子查询是将一个查询语句嵌套在另一个查询语句中。通过子查询,可以实现多表之间的查询。自查询中常用的操作符有ANY(SOME)、ALL、IN、EXISTS。
- 带ANY、SOME、ALL操作符的子查询
ALL和ANY操作符的常见用法是结合一个比较操作符对一个数据列子查询的结果进行比较。它们检查比价值是否与子查询所返回的全部或一部分值匹配。 - IN和NOT IN查询
带IN关键字进行查询时,内层查询仅返回一个数据列的集合。该集合将提供给外层查询进行比较操作。
使用多表连接的查询结果与使用IN关键字的查询结果相同。
使用NOT IN关键字的嵌套不能使用多表连接查询实现。如果确定子查询只返回一个单一时,IN关键字可以换成=操作符。 - EXISTS和NOT EXISTS子查询
EXISTS和NOT EXISTS操作符只测试某个子查询是否返回了数据行:如果是,EXISTS将是true,NOT EXISTS将是false。在使用EXISTS和NOT EXISTS操作符时,子查询中的SELECT子句通常使用“*”。这两个操作符是根据子查询是否返回了数据行来判断真假的,不关心数据行所包含的内容是什么,所以没必要明确地列出数据列的名字。
8.9 合并查询结果
MySQL中使用UNION关键字,可以将多个SELECT结果集合并为单个结果集,但要求参加合并的结果集对应的列数和数据类型必须相同。在第一个SELECT语句中被使用的列名称也被用于结果的列名称。语法格式如下:
SELECT …
UNION [ALL | DISTINCT]
SELECT…
[UNION [ALL | DISTINCT]
SELECT…]
语法中不适用关键词ALL,则所有返回的行都是唯一的。指定了ALL,SELECT语句中得到所有匹配的行都会出现。DISTINCT关键词是一个自选词,不起任何作用,但是根据SQL标准的要求,在语法中允许采用。
8.10 使用正则表达式进行查询
在MySQL中使用REGEXP关键字来匹配查询正则表达式,基本形式如下:
属性名 REGEXP ‘匹配方式’
- 模式字符“^”
含义为匹配以特定字符或字符串开头的记录。 - 模式字符“$”
含义为匹配以特定字符或字符串结尾的记录。 - 模式字符“.”
含义为匹配字符串中任意一个字符,包括Enter或者换行等。 - 模式字符“[字符集合]”
含义为匹配字符集合中任意一个字符。
还可以指定集合区间,例如[4-10]指定集合区间的所有数字 - 模式字符“[^字符集合]”
含义是匹配不在指定字符集合中的任何字符。 - 模式字符“S1|S2|S3”
含义为匹配S1、S2、S3中的任意一个字符串。 - 模式字符“*”
含义为匹配多个该字符之前的字符,包括 0 个和 1 个。 - 模式字符“+”
含义为匹配多个该字符之前的字符,包括 1 个。 - 模式字符“字符串{N}”
N表示前面的字符串至少要出现N次。 - 模式字符“字符串{M,N}”
匹配方式中的M和N表示前面的字符串出现至少M次,最多N次。
8.12 高手点拨
- 使用 GROUP BY 子句一定要用统计函数吗?
不一定,当只需查询有哪些组时,不适用统计函数。 - 当使用ROLLUP时,是否可以使用ORDER BY子句对结果进行排序?
不行,当使用ROLLUP时,不能同时使用ORDER BY子句进行结果排序。ROLLUP和ORDER BY是互相排斥的。 - WHERE语句与HAVING语句的区别?
WHERE子句的查询条件在进行分组之前决定行的取舍,而HAVING查询条件在进行分组之后决定每一组的取舍;WHERE子句不能包含统计函数,而HAVING子句可以包含统计函数。 - LIKE和REGEXP的区别?
LIKE匹配整个列。如果被匹配的文本仅在列值中出现,LIKE并不会找到它,相应的行也不会返回。而REGEXP在列值内进行匹配,如果被匹配的文本在列值中出现,REGEXP将会找到它,相应的行将被返回。