增删查改
SELECT 语句来查询数据。查询数据是指从数据库中根据需求,使用不同的查询方式来获取不同的数据,是使用频率最高、最重要的操作。
查询表内所有数据
select *
from 表名;
一般情况下,除非需要使用表中所有的字段数据,否则最好不要使用通配符“*”。
虽然使用通配符可以节省输入查询语句的时间,但是获取不需要的列数据通常会降低查询和所使用的应用程序的效率。
使用“*”的优势是,当不知道所需列的名称时,可以通过“*”获取它们。
查询表中的某一个字段的语法格式为:
SELECT < 列名 > FROM < 表名 >;
查询 tb_students_info 表中 name 列所有学生的姓名
select name
from tb_students_info;
使用 SELECT 声明可以获取多个字段下的数据,只需要在关键字 SELECT 后面指定要查找的字段名称,
不同字段名称之间用逗号“,”分隔开,最后一个字段后面不需要加逗号,语法格式如下:
SELECT <字段名1>,<字段名2>,…,<字段名n> FROM <表名>;
从 tb_students_info 表中获取 id、name 和 height 三列
select id,name,height
from tb_students_info;
有时出于对数据分析的要求,需要消除重复的记录值。这时候就需要用到 DISTINCT 关键字指示 MySQL 消除重复的记录值,语法格式为:
SELECT DISTINCT <字段名> FROM <表名>;
查询 tb_students_info 表中 age 字段的值,返回 age 字段的值且不得重复
select distinct age
from tb_students_info;
在使用 MySQL SELECT 语句时往往返回的是所有匹配的行,有些时候我们仅需要返回第一行或者前几行,这时候就需要用到 MySQL LIMT 子句。
基本的语法格式如下:
<LIMIT> [<位置偏移量>,] <行数>
LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。
显示 tb_students_info 表查询结果的前 4 行
select name
from tb_students_info limit 4;
在 tb_students_info 表中,使用 LIMIT 子句返回从第 4 条记录开始的行数为 5 的记录
select name
from tb_students_info limit 3,5;
ORDER BY 子句主要用来将结果集中的数据按照一定的顺序进行排序。
其语法格式为:
ORDER BY {<列名> | <表达式> | <位置>} [ASC|DESC]
语法说明如下
1) 列名
指定用于排序的列。可以指定多个列,列名之间用逗号分隔。
2) 表达式
指定用于排序的表达式。
3) 位置
指定用于排序的列在 SELECT 语句结果集中的位置,通常是一个正整数。
4) ASC|DESC
关键字 ASC 表示按升序分组,关键字 DESC 表示按降序分组,其中 ASC 为默认值。这两个关键字必须位于对应的列名、表达式、列的位置之后。
使用 ORDER BY 子句应该注意以下几个方面:
ORDER BY 子句中可以包含子查询。
当排序的值中存在空值时,ORDER BY 子句会将该空值作为最小值来对待。
当在 ORDER BY 子句中指定多个列进行排序时,MySQL 会按照列的顺序从左到右依次进行排序。
查询的数据并没有以一种特定的顺序显示,如果没有对它们进行排序,则将根据插入到数据表中的顺序显示。使用 ORDER BY 子句对指定的列数据进行排序。
查询 tb_students_info 表的 height 字段值,并对其进行排序
select *
from tb_students_info order by height;
有时需要根据多列进行排序。对多列数据进行排序要将需要排序的列之间用逗号隔开。
查询 tb_students_info 表中的 name 和 height 字段,先按 height 排序,再按 name 排序
select height,name
from tb_students_info order by height,name;
注意:在对多列进行排序时,首行排序的第一列必须有相同的列值,才会对第二列进行排序。如果第一列数据中所有的值都是唯一的,将不再对第二列进行排序
查询 tb_students_info 表,先按 height 降序排序,再按 name 升序排序
select height,name
from tb_students_info order by height desc,name asc;
注意:DESC 关键字只对前面的列进行降序排列,在这里只对 height 排序,而并没有对 name 进行排序,因此,height 按降序排序,
而 name 仍按升序排序,如果要对多列进行降序排序,必须要在每一列的后面加 DESC 关键字。
在使用 MySQL SELECT语句时,可以使用 WHERE 子句来指定查询条件,从 FROM 子句的中间结果中选取适当的数据行,达到数据过滤的效果。
语法格式如下:
WHERE <查询条件> {<判定运算1>,<判定运算2>,…}
在表 tb_students_info 中查询身高为 170cm 的学生的姓名
select name
from tb_students_info
where height = 170;
查询年龄小于 22 的学生的姓名
select name
from tb_students_info
where age < 22;
在 tb_students_info 表中查询 age 大于 21,并且 height 大于等于 175 的学生的信息
select *
from tb_students_info
where age > 21 and height >= 175;
1) 百分号(%)
百分号是 MySQL 中常用的一种通配符,在过滤条件中,百分号可以表示任何字符串,并且该字符串可以出现任意次。
使用百分号通配符要注意以下几点:
MySQL 默认是不区分大小写的,若要区分大小写,则需要更换字符集的校对规则。
百分号不匹配空值。
百分号可以代表搜索模式中给定位置的 0 个、1 个或多个字符。
尾空格可能会干扰通配符的匹配,一般可以在搜索模式的最后附加一个百分号。
2) 下划线(_)
下划线通配符和百分号通配符的用途一样,下画线只匹配单个字符,而不是多个字符,也不是 0 个字符。
注意:不要过度使用通配符,对通配符检索的处理一般会比其他检索方式花费更长的时间。
在 tb_students_info 表中,查找所有以“T”字母开头的学生姓名
select name
from tb_students_info
where name like "T%";
在 tb_students_info 表中,查找所有包含“e”字母的学生姓名
select name
from tb_students_info
where name like "%e%";
在 tb_students_info 表中,查找所有以字母“y”结尾,且“y”前面只有 4 个字母的学生的姓名
select name
from tb_students_info
where name like "____y";
在表 tb_students_info 中查询注册日期在 2016-01-01 之前的学生的信息
select *
from tb_students_info
where login_date < '2016-01-01';
在表 tb_students_info 中查询注册日期在 2015-10-01 和 2016-05-01 之间的学生的信息
select *
from tb_students_info
where login_date between '2015-10-01' and '2016-01-01';
tb_students_info 表和 tb_departments 表之间,使用 INNER JOIN 语法进行内连接查询
select *
from tb_students_info inner join tb_departments
where tb_students.dept_id = tb_departments.dept_id;
MySQL 中内连接是在交叉连接的结果集上返回满足条件的记录;
而外连接先将连接的表分为基表和参考表,再以基表为依据返回满足和不满足条件的记录。
外连接更加注重两张表之间的关系。按照连接表的顺序,可以分为左外连接和右外连接。
左外连接又称为左连接,在 FROM 子句中使用关键字 LEFT OUTER JOIN 或者 LEFT JOIN,用于接收该关键字左表(基表)的所有行,并用这些行与该关键字右表(参考表)中的行进行匹配,即匹配左表中的每一行及右表中符合条件的行。
在左外连接的结果集中,除了匹配的行之外,还包括左表中有但在右表中不匹配的行,对于这样的行,从右表中选择的列的值被设置为 NULL,即左外连接的结果集中的 NULL 值表示右表中没有找到与左表相符的记录。
在 tb_students_info 表和 tb_departments 表中查询所有学生,包括没有学院的学生
select *
from tb_students_info left join tb_departments
on tb_students_indo.dept_id = tb_departments;
右外连接又称为右连接,在 FROM 子句中使用 RIGHT OUTER JOIN 或者 RIGHT JOIN。与左外连接相反,右外连接以右表为基表,连接方法和左外连接相同。在右外连接的结果集中,除了匹配的行外,还包括右表中有但在左表中不匹配的行,对于这样的行,从左表中选择的值被设置为 NULL。
在 tb_students_info 表和 tb_departments 表中查询所有学院,包括没有学生的学院
select *
from tb_students_info right join tb_departments
on tb_students_info.dept_id = tb_departments.dept_id;
子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从 MySQL 4.1 开始引入,在 SELECT 子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或者多个表。
子查询中常用的操作符有 ANY(SOME)、ALL、IN 和 EXISTS。
子查询可以添加到 SELECT、UPDATE 和 DELETE 语句中,而且可以进行多层嵌套。子查询也可以使用比较运算符,如“<”、“<=”、“>”、“>=”、“!=”等。
在 tb_departments 表中查询 dept_type 为 A 的学院 ID,并根据学院 ID 查询该学院学生的名字
select name
from tb_students_info
where dept_id in (select dept_id
from tb_departments
where dept_type = 'A');
在 MySQL SELECT 语句中,允许使用 GROUP BY 子句,将结果集中的数据行根据选择列的值进行逻辑分组,以便能汇总表内容的子集,实现对每个组而不是对整个结果集进行整合。
语法格式如下:
GROUP BY { <列名> | <表达式> | <位置> } [ASC | DESC]
根据 dept_id 对 tb_students_info 表中的数据进行分组,将每个学院的学生姓名显示出来
select name
from tb_students_info
group by dept_id;
在 MySQL SELECT 语句中,除了能使用 GROUP BY 子句分组数据外,还可以使用 HAVING 子句过滤分组,在结果集中规定了包含哪些分组和排除哪些分组。
HAVING 子句和 WHERE 子句非常相似,HAVING 子句支持 WHERE 子句中所有的操作符和语法,但是两者存在几点差异:
WHERE 子句主要用于过滤数据行,而 HAVING 子句主要用于过滤分组,即 HAVING 子句基于分组的聚合值而不是特定行的值来过滤数据,主要用来过滤分组。
WHERE 子句不可以包含聚合函数,HAVING 子句中的条件可以包含聚合函数。
HAVING 子句是在数据分组后进行过滤,WHERE 子句会在数据分组前进行过滤。WHERE 子句排除的行不包含在分组中,可能会影响 HAVING 子句基于这些值过滤掉的分组。
根据 dept_id 对 tb_students_info 表中的数据进行分组,并显示学生人数大于1的分组信息
select *
from tb_students_info
group by dept_id
having count(name) > 1;
MySQL 中使用 REGEXP 关键字指定正则表达式的字符匹配模式
在 tb_departments 表中,查询 dept_name 字段以字母“C”开头的记录
select *
from tb_departments
where dept_name regexp 'C'
INSERT INTO <表名> [ <列名1> [ , … <列名n>] ]
VALUES (值1) [… , (值n) ];
语法说明如下。
<表名>:指定被操作的表名。
<列名>:指定需要插入数据的列名。若向表中的所有列插入数据,则全部的列名均可以省略,直接采用 INSERT<表名>VALUES(…) 即可。
VALUES 或 VALUE 子句:该子句包含要插入的数据清单。数据清单中数据的顺序要和列的顺序相对应。
在 tb_courses 表中插入一条新记录,course_id 值为 2,course_name 值为“Database”,course_grade 值为 3,info值为“MySQL”
insert into tb_course (course_id,course_name,course_grade,info)
values(2,'Database',3,'mysql')
UPDATE <表名> SET 字段 1=值 1 [,字段 2=值 2… ] [WHERE 子句 ]
[ORDER BY 子句] [LIMIT 子句]
语法说明如下:
<表名>:用于指定要更新的表名称。
SET 子句:用于指定表中要修改的列名及其列值。其中,每个指定的列值可以是表达式,也可以是该列对应的默认值。如果指定的是默认值,可用关键字 DEFAULT 表示列值。
WHERE 子句:可选项。用于限定表中要修改的行。若不指定,则修改表中所有的行。
ORDER BY 子句:可选项。用于限定表中的行被修改的次序。
LIMIT 子句:可选项。用于限定被修改的行数。
注意:修改一行数据的多个列值时,SET 子句的每个值用逗号分开即可。
在 tb_courses_new 表中,更新所有行的 course_grade 字段值为 4
update tb_courses_new set course_grade = 4;
在 tb_courses 表中,更新 course_id 值为 2 的记录,将 course_grade 字段值改为 3.5,将 course_name 字段值改为“DB”
update tb_courses_new set course_grade = 3.5,course_id = 2
where course_name = 'DB';
DELETE FROM <表名> [WHERE 子句] [ORDER BY 子句] [LIMIT 子句]
语法说明如下:
<表名>:指定要删除数据的表名。
ORDER BY 子句:可选项。表示删除时,表中各行将按照子句中指定的顺序进行删除。
WHERE 子句:可选项。表示为删除操作限定删除条件,若省略该子句,则代表删除该表中的所有行。
LIMIT 子句:可选项。用于告知服务器在控制命令被返回到客户端前被删除行的最大值。
注意:在不使用 WHERE 条件的时候,将删除所有数据
删除 tb_courses_new 表中的全部数据
delete form tb_courses_new;
在 tb_courses_new 表中,删除 course_id 为 4 的记录
delete from tb_courses_new where course_id = 4;