一、插入数据
1、为表的所有字段插入数据
通常情况下,插入的新纪录要包含表的所有字段
INSERT 语句有两种方式可以同时为表的所有字段插入数据,第一种方式是不指定具体的字段名,第二种方式是列出表的所有字段。
(1)INSERT 语句中不指定具体的字段名
语法规则:
INSERTINTO 表名 VALUES(值1,值2,…,值n)
【例1】向 student 表中插入记录
注意:student 表包含 6 个字段,那么 INSERT 语句中的值也应该是 6 个。而且数据类型也应该与字段的数据类型一致。Sno,sname,ssex,sbirth,zno 和 sclass 这 6 个字段是字符串类型,取值必须加上引号。如果不加上引号,数据库系统会报错。
(2)INSERT 语句中列出所有字段
语法规则:
INSERT INTO 表名(字段名1,字段名2,…,字段名n)
VALUES(值1,值2,…,值n);
【例2】向 student 表中插入记录
注意:如果表的字段比较多,用第二种方法就比较麻烦。但是,第二种方法比较灵活。可以随意地设置字段的顺序,而不需要按照表定义时的顺序。值的顺序也必须跟着字段顺序的改变而改变。
【例3】向 student 表中插入一条新记录。INSERT 语句中字段的顺序与表定义时的顺序不同。
注意:sbirth 字段和 ssex 字段的顺序发生了改变。其对于值的位置也跟着发生了改变。
2、为表的指定字段插入数据
语法规则:
INSERT INTO 表名(字段名1,字段名2,…,字段名n)
VALUES(值1,值2,…,值n);
【例4】向 student 表的sno,sname 和 ssex 这 3 个字段插入数据
注意:这种方式也可以随意的设置字段的顺序,而不需要按照表定义时的顺序。
3、同时插入多条记录
语法规则:
INSERT INTO 表名 [(字段名列表)]
VALUES(取值列表1), (取值列表2), …(取值列表n);
【例5】向 student 表的 sno,sname 和 ssex这 3 个字段插入数据。总共插入 3 条记录
【例6】向 student 表插入 3 条记录
注意:不指定字段时,必须为每个字段都插入数据。如果指定字段,就只需要为指定的字段插入数据。
【例7】向 student 表的 sno,sname 和 ssex 字段插入数据。INSERT 语句中,这 3 个字段的顺序可以任意排列。
技巧:向 MySQL 的某个表中插入多条记录时,可以使用多个 INSERT 语句逐条插入记录,也可以使用一个 INSERT 语句插入多条记录。选择哪种方式通常根据个人喜好来决定。如果插入的记录很多时,一个 INSERT 语句插入多条记录的方式的速度会比较快。
二、修改数据
修改数据是更新表中已经存在的记录。在 MySQL 中,通过 UPDATE 语句来修改数据。
语法规则:
UPDATE 表名
SET 字段名1=值1, 字段名2=值2, … 字段名n=值n
WHERE 条件表达式
【例8】更新 student 表中 sno 值为 1418855243 的记录。将 sname 字段的值变为 '李壮'。将 sbirth 字段的值变为 '1996-03-23'
说明:表中满足条件表达式的记录可能不止一条。使用 UPDATE 语句会更新所有满足条件的记录。但在 MySQL 中是需要一条一条的执行。
【例9】更新 student 表中 sname 值为李凯的记录。将 sbirth 字段的值变为 "1997-01-01"。将 ssex 字段的值变为 "女"。
结果显示更新了两条数据
三、删除数据
删除数据是删除表中已经存在的记录,在 MySQL 中,通过 DELETE 语句来删除数据
语法规则:
DELETE FROM 表名 [WHERE 条件表达式]
【例10】删除 student 表中 sno 值为 1418855243 的记录
DELETE 语句可以同时删除多条记录。
【例11】删除 student 表中 sclass 的值为 '商务1301' 的记录。
注意:DELETE 语句中如果不加上“WHERE条件表达式”,数据库系统会删除指定表中的所有数据。需谨慎使用。
四、单表查询
1、select 语法
语法规则:
select [ all | distinct] <目标列表达式> [别名] [ , <目标列表达式> [别名] ]...
from <表名或视图名> [别名] [ , <表名或视图名> [别名] ]...
[where <条件表达式>]
[group by <列名1> ]
[having <条件表达式> ]
[order by <列名2> [ ASC| DESC ]]
[limit 字句]
-- 其中[]内的内容是可选的。
2、简单查询
(1)查询所有字段
查询所有字段是指查询表中的所有字段的数据,有两种方式:一种是列出表中的所有字段,另一种是使用通配符 “*” 来查询
注意:通过使用通配符 *,可以查询表中所有字段的数据,这种方式比较简单,尤其是数据库表中的字段很多时,这种方式更加明显。但是从显示结果顺序的角度 来讲,使用通配符 * 不够灵活。如果要改变显示字段的顺序,可以选择使用第一种方式。
【例12】查询学生的所有信息,使用列出表中的所有字段方式查询。
【例12】查询学生的所有信息,使用使用通配符 * 方式查询。
(2)指定字段查询
虽然通过 select 语句可以查询所有字段,但有些时候,并不需要将表中的所有字段都显示出来,只需要查询我们需要的字段就可以了,这就需要我们在 select 中指定需要的字段。
【例13】查询学生的学号和姓名
(3)DISTINCT 避免重复数据查询
distinct 关键字可以去除重复的查询记录。和 distinct 相对的是 all 关键字,即显示所有的记录(包括重复的),而 all 关键字是系统默认的。
注意:查询的字段必须包含在表中。如果查询的字段不在表中,系统会报错。例如,在 student 表中查询 weight 字段,系统会出现 “ERROR 1054 (42522): Unknown column 'weight' in 'field list'” 这样的错误提示信息。
【例14】查询在 student 表中都有哪些班级
1)all 关键字查询结果
2)distinct 关键字查询结果
(4)为表和字段取别名
有时为了显示结果更加直观,需要一个更加直观的名字来表示这一列,而不是用数据库中的列的名字。
语法格式:
select [ all | distinct] <目标列表达式> [AS] [别名] [ , <目标列表达式> [AS] [别名] ]...
from <表名或视图名> [别名] [ , <表名或视图名>[别名] ]...
【例15】查询学号为 1414855328 的学生的学号,姓名和计算机应用软件的成绩。并指定返回的结果中的列名为学号,姓名和计算机应用软件的成绩,而不是sno、sname 和 grade。
【例16】查询 student 表中字段 ssex 的值,如果为男的变为 “M”,为女的变为 “F”,同时在结果集中显示的列名改为 “性别”
说明:这里使用了 Limit 关键字,限制返回的符合结果数量。其详细用法在后来会讲到。
3、条件查询
条件查询主要使用关键字 where 指定查询的条件。
注意:条件表达式中设置的条件越多,查询出来的记录就会越少。
(1)带关系运算符和逻辑运算符的查询
MySQL 中,可以通过关系运算符和逻辑运算符来编写 “条件表达式”。
【例18】查询成绩大于 90 分的学生的学号以及分数
【例19】查询成绩等于 96 或者在 70 分到 80 分之间但不等于 75 的学生的学号,成绩
(2)带 IN 关键字的查询
IN 关键字可以判断某个字段的值是否在指定的集合中。
语法格式:
[NOT] IN (元素1, 元素2, 元素3, ... )
【例20】查询成绩在集合 (65,75,85,95) 中的学生的学号和成绩
(3)带 BETWEEN...AND 关键字的查询
between...and 关键字可以判断读某个字段的值是否在指定的范围内
语法格式:
[ NOT ] between 取值1 and 取值2
【例21】查询成绩在 75 分到 80 分之间学生的学号,和成绩。包含 75 分和 80 分。
【例22】下面使用 NOT BETWEEN AND 关键字查询 student 表。查询条件是 sno 字段的取值不在 1418855240 ~ 1418855242 之间。
技巧:BETWEEN AND 和 NOT BETWEEN AND 关键字在查询指定范围的记录时很有用。例如,查询学生成绩表的年龄段、分数段等。还有查询员工的工资水平时也可以使用这两个关键字。
(4)带 IS NULL 关键字的空值查询
is null关键字可以用来判断字段的值是否为空值(NULL)。
语法格式:
is [ not ] null
【例23】查询还没有分专业的学生的学号和姓名
注意:IS NULL 是一个整体,不能将 IS 换成 “=” ,
zno=null 表示要查询的 zno 的值是字符串 “null” ,而不是空值。
(5)带 LIKE 关键字的查询
like 关键字可以匹配字符串是否相等
语法规则:
[ not ] like "字符串"
【例24】下面使用 LIKE 关键字来匹配一个完整的字符串 '马小梅'。
说明:使用 LIKE 关键字和使用 “=” 的效果是一样的。但是,这只对匹配一个完整的字符串这种情况有效。如果字符串中包含了通配符,就不能这样进行替换了。
【例25】下面使用 NOT LIKE 关键字来查询不是姓李的所有人的记录
说明:使用 LIKE 和 NOT LIKE 关键字可以很好地匹配字符串。而且,可以使用 “%” 和 “_” 这两个通配字符来简化查询。
4、高级查询
(1)分组查询
GROUP BY 关键字可以将查询结果按某个字段或多个字段进行分组。
语法格式:
GROUP BY 字段名 [HAVING 条件表达式] [WITH ROLLUP]
【例26】按 student 表的 ssex 字段进行分组查询
说明:如果单独使用 GROUP BY 关键字,查询结果只显示一个分组的一条记录。
【例27】按 student 表的 ssex 字段进行分组查询。然后显示记录数大于等于 10 的分组。
说明: “HAVING条件表达式” 与 “WHERE条件表达式” 都是用来限制显示的。但是,两者起作用的地方不一样。“WHERE条件表达式” 作用于表或者视图,是表和视图的查询条件。“HAVING条件表达式” 作用于分组后的记录,用于选择满足条件的组。
(2)对查询结果排序
ORDER BY 关键字对记录进行排序
语法格式:
order by 字段名 [ asc | desc ]
【例28】查询 student 表中所有记录,按照 zno 字段进行排序
MySQL 中,可以指定按多个字段进行排序
【例29】查询 student 表中所有记录,按照 zno 字段的升序方式和 sno 字段的降序方式进行排序。
(3)限制查询结果数量
LIMIT 子句用来限制被 SELECT 语句返回的行数。
语法格式:
LIMIT {[offset,] row_count | row_count OFFSET offset}
【例30】在 student 表中查找从第 3 名同学开始的之后 3 位学生的信息。
(4)聚合函数
聚合函数包括 COUNT()、SUM()、 AVG(), MAX() 和 MIN()。其中:
COUNT() 用来统计记录的条数;
SUM() 用来计算字段的值的总和;
AVG() 用来计算字段的值的平均值;
MAX() 用来查询字段的最大值;
MIN() 用来查询字段的最小值。
【例31】使用 COUNT() 函数统计 student 表的记录数
【例32】使用 SUM() 函数统计 sc 表中学号为 1414855328 的同学的总成绩。
五、多表查询
(1)首先准备员工表和部门表
-- 建表 create table department( id int, name varchar(20)); create table employee1( id int primary key auto_increment, name varchar(20), sex enum('male', 'female') not null default 'male', age int, dep_id int ); -- 插入数据 insert into department values (200, '技术'), (201, '人力资源'), (202, '销售'), (203, '运营'); insert into employee1(name,sex,age,dep_id) values ('赵一', 'male', 18, 200), ('钱二', 'female', 48, 201), ('孙三', 'male', 38, 201), ('李四', 'female', 28, 202), ('周五', 'male', 18, 200), ('吴六', 'female', 18, 204);
查看表
(2)多表连接查询
1)交叉连接:不适用于任何匹配条件。生成笛卡尔积
select * from employee1, department;
2)内连接:找两张表共有的部分,相当于利用条件从笛卡尔积结果中筛选出了正确的结果。(只连接匹配的行)
-- department没有204这个部门,因而employee表中关于204这条员工信息没有匹配出来
select * from employee1, department where employee1.dep_id=department.id;
-- 上面用where表示的可以用下面的内连接表示,建议使用下面的那种方法
select * from employee1 inner join department on employee1.dep_id=department.id;
-- 也可以这样表示
select employee1.id, employee1.name, employee1.age, employee1.sex, department.name
from employee1, department where employee1.dep_id=department.id;
注意:内连接的 join 可以忽略不写,但是还是加上看起来清楚点
3)左连接:左表的记录将会被全部显示出来,而右表只会显示符合搜索条件的记录,右表记录不足的地方均为 NULL
-- 左链接:在按照on的条件取到两张表共同部分的基础上,保留左表的记录
select * from employee1 left join department on department.id=employee1.dep_id;
select * from department left join employee1 on department.id=employee1.dep_id;
4)右连接:左表只会显示符合搜索条件的记录,右表的记录将会被全部显示出来,左表记录不足的地方均为 NULL
-- 右链接:在按照on的条件取到两张表共同部分的基础上,保留右表的记录
select * from employee1 right join department on department.id=employee1.dep_id;
select * from department right join employee1 on department.id=employee1.dep_id;
5)全外连接:显示左右两个表的全部记录
注意:MySQL 不支持全外连接 full join,但可以使用 union 实现全外连接
select * from employee1 left join department on department.id=employee1.dep_id
union
select * from employee1 right join department on department.id=employee1.dep_id;
(3)符合条件的连接查询
示例1:以内连接的方式查询 employee 和 department 表,并且 employee 表中的 age 字段值必须大于 25,即找出公司所有部门中年龄大于 25 岁的员工
select * from employee1
inner join department on employee1.dep_id=department.id and age > 25;
示例2:以内连接的方式查询 employee 和 department 表,并且以 age 字段的升序方式显示
select * from employee1
inner join department on employee1.dep_id=department.id and age > 25
order by age asc;
六、子查询
在具体应用中,如果需要实现多表数据记录查询,一般不使用连接查询,因为该操作效率比较低,于是 MySQL 提供了连接查询的替代操作 —— 子查询操作。
通过子查询,可以实现多表之间的查询。子查询中可能包括 IN, NOT IN,ANY,EXISTS 和 NOT EXISTS 等关键字。子查询中还可能包含比较运算符,如 “=”、“!=”、“>” 和 “<” 等。
(1)带 IN 关键字的子查询
IN 关键字可以判断某个字段的值是否在指定的集合中。
【例33】查询成绩在集合 (65,75,85,95) 中的学生的学号和成绩
【例34】查询选修过课程的 student 的记录
(2)带 EXISTS 关键字的子查询
exists 关键字表示存在,使用 exists 关键字时,内查询语句不返回查询的记录。
【例35】如果存在 “金融” 这个专业,就查询所有的课程信息
【例36】如果存在 “计算机科学与技术” 这个专业,就查询所有的课程信息
(3)带 ANY 关键字的子查询
ANY 关键字表示满足其中任何一个条件。
【例37】查询比其他班级比计算 1401 班级某一个同学年龄小的学生的姓名和年龄
(4)带 ALL 关键字的子查询
ALL 关键字表示满足所有的条件
【例38】查询比其他班级比计算 1401 班级所有同学年龄都大的学生的姓名和年龄