前言
上一篇我们学习了如何从数据库的表中更新数据和删除数据,本篇主要讲如何从数据库表中查询数据,包括一般查询、条件查询以及模糊查询。学习之前可以在你的数据库中先导入这个sql脚本:school.sql
一、检索数据(基础查询)
检索数据需要使用的关键字:
- SELECT:从列中检索数据,SELECT后面紧跟要检索的列,或者使用通配符*检索所有列。
- FROM:指定从哪个表中检索数据,后面紧跟表名
1.1 检索单个列
检索单个列的语法如下:
SELECT 列名 FROM 表名;
例如:
SELECT student_name FROM t_student;
运行结果如下所示:
可以看到该sql语句将表t_student中所有行的student_name列中的数据检索出来了。
1.2 检索多个列
检索多个列需要在SELECT关键字后给出多个列名,每个列之间用逗号分隔,语法如下:
SELECT 列名1,列名2 FROM 表名;
例如:
SELECT student_name,age FROM t_student;
结果:
可以看到以上sql语句成功检索出了指定的列。
1.3 检索所用列
检索所有的列需要使用通配符*,语法如下:
SELECT * FROM 表名;
例如,查询学生表t_student中的所有列:
SELECT * FROM t_student;
1.4 检索不同的行(即返回没有重复的数据)
有时候查询的时候会返回很多重复的数据,如果我们想要返回的每一条数据都没有重复,则可以使用
关键字DISTINCT 来指示mysql返回唯一不同的值,语法如下:
SELECT DISTINCT 列名 FROM 表名;
需要注意的是关键字DISTINCT只能返回它的目标字段,而无法返回其它字段。也就是说使用DISTINCT返回的是不重复的记录,而不是返回指定列不同的记录。比如:
SELECT DISTINCT id,student_name FROM t_student;
以上查询的是id和student_name都不同的数据,而不是单独id不同的数据(即id一样但是student_name不同的数据也能返回)。同时DISTINCT只能位于第一个列名前面,不能放到后面的列名前。
1.5 限制结果
使用LIMIT 关键字限定返回的结果
- LIMIT关键字指定返回不多于xx行的数据
SELECT student_name FROM t_student LIMIT 5;
- LIMIT指定返回从行5开始的5行
SELECT student_name FROM t_student LIMIT 5,5;
注意:行0 检索出来的第一行为行0而不是行1。因此LIMIT 1,1将检索第二行而不是第一行
mysql5支持另一种语法:LIMIT 4 OFFSET 3 从行3开始取4行,等价于 LIMIT 3,4
1.6 使用完全限定的表名
SELECT t_student .student_name FROM t_student ;
二、排序
使用ORDER BY子句,可以对一个列或者多个列进行排序
可以使用非检索的列进行排序,也就是说要排序的列不一定要检索出来。
2.1 单个排序
SELECT student_name FROM t_student ORDER BY student_name
2.2 多个列排序
多个列排序只需要在ORDER BY 子句后指定多个列名,每个列用逗号分隔。首先按照第一个列排序,第一个列相同时才按照第二个排序。如果第一个列的数据完全不同,则不按第二个列排序
SELECT id,student_name FROM t_student ORDER BY student_name,id
2.3 指定排序方向
- ASC:升序(默认)
- DESC:降序
DESC关键只能用在直接位于其前面的列名,如果想在多个列进行降序排序,必须为每个列指定DESC关键字 - 根据单个列降序
SELECT student_name FROM t_student ORDER BY student_name DESC
- 根据多个列降序
SELECT id,student_name FROM t_student ORDER BY student_name,id DESC
ORDER BY 子句位于FROM子句之后,如果使用LIMIT,LIMIT子句应该位于ORDER BY子句之后
三、过滤数据
- 使用WHERE子句过滤数据
数据库表一般包含大量的数据,很少需要检索表中所有行,一般只会根据特定操作或者报告的需要提前表数据的子集。只检索所需数据需要指定搜索条件(search criteria),搜索条件也叫过滤条件(filter condition)
在SELECT语句中,数据库根据WHERE子句中指定的搜索条件进行过滤。WHERE子句在表名(FROM子句)给出之后,如下所示:
SELECT * FROM t_student WHERE student_name = "李四";
WHERE子句的操作符
操作符 | 说明 |
---|---|
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
BETWEEN | 两者之间 |
- 使用WHERE子句过滤单个值
SELECT * FROM t_student WHERE age > 15;
- 不匹配检查
使用!=操作符进行不匹配检查。
SELECT * FROM t_student WHERE student_name != "李四";
- 范围值检查
使用BETWEEN关键字进行范围检查。
用法:BETWEEN a AND b
在使用BETWEEN关键字的时候必须指定低端值和高端值,两者之间用AND连接
SELECT * FROM t_student WHERE age BETWEEN 15 AND 20;
- 空值检查
使用 IS NULL子句
SELECT * FROM t_student WHERE student_name IS NULL;
这条语句返回student_name字段为空值的数据
四、组合WHERE子句
操作符(operator)用来连接或改变WHERE子句中的子句的关键字,也称逻辑操作符(logical operator)
4.1 AND操作符
AND:用在WHERE子句之后的关键字,用来检索满足所有给定条件的行。
为了通过不止一个列进行过滤,可以使用AND操作符给WHERE子句附加条件。
SELECT * FROM t_student WHERE age<15 AND student_name="李四";
4.2 OR操作符
OR操作符指示mysql检索匹配任一条件的行
SELECT * FROM t_student WHERE age<15 OR student_name="李四";
默认计算次序AND优先于OR,也就是说 a OR b AND c 等价于a OR (b AND c)。可以使用括号改变默认顺序
4.3 IN操作符
IN操作符用来指定条件范围,范围中的每个值都可以进行匹配,功能与OR相当。用法如下:
IN(a,b);
检索学生年龄在15到20之间的学生
SELECT * FROM t_student WHERE age IN(15,20);
IN操作符的优点:
- 在使用长的合法选项清单时,IN操作符的语法更清楚且更直观
- 在使用IN操作符时,计算的次序更容易管理,因为操作符更少
- IN操作符一般比OR操作符执行更快
- IN操作符的最大优点是可以包含其他SELECT语句,使得能够更动态地建立WHERE子句。
4.4 NOT操作符
NOT操作符有且只有一个作用:否定它之后所跟的任何条件
SELECT column1_name,column2_name WHERE NOT IN(1002,1003);
检索column1_name不等于1002和1003的数据
mysql支持NOT 对IN、BETWEEN和EXIST子句取反
五、使用通配符进行过滤
通配符:用来匹配值的一部分的特殊字符
搜索模式:由字面值、通配符或者两者组合构成的搜索条件
通配符必须跟在LIKE操作符后面。LIKE指示mysql,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较
5.1 百分号(%)通配符
百分号表示任意字符出现任意次数,比如检索所有姓李的学生:
SELECT * FROM t_student WHERE student_name LIKE '李%';
通配符可以在搜索模式中任意位置使用,并且可以使用多个通配符,比如检索名字中间有四的学生
SELECT * FROM t_student WHERE student_name LIKE '%李%';
注意:
%可以匹配0个字符,另外尾空格会干扰通配符,也就说说’%get ‘不会匹配到get结尾的数据,因为后面有一个空格。解决办法是在末尾加一个%或者使用函数去掉空格
%不会匹配到NULL
5.2 下划线通配符(_)
下划线的用途和%一样,但下划线只匹配单个字符而不是多个字符,比如检索不管姓什么但是名字为宏的学生:
SELECT * FROM t_student WHERE student_name LIKE '_宏';
通配符使用技巧
- 不要过度使用通配符。通配符的搜索比其他搜索慢,因此如果其他操作符能够达到目的,应该使用其他操作符。
- 在确实需要使用通配符的时候,除非绝对必要,否则不要把他们用在搜索模式的开始处。把通配符放在开始处查询起来是最慢的。
- 仔细通配符的位置。如果放错地方,可能不会返回想要的数据