文章目录
数据的增、删、改、查
插入数据
-- 1.常规操作,使用字段对应的数值直接插入数据表中
INSERT [INTO] tbl_name [(col_name, ...)] VALUES (value, ...)[, (value, ...)];
-- 2.为指定的字段赋值
INSERT [INTO] tbl_name SET col_name = value,...;
-- 3.使用SELECT查询将查询结果插入数据表中
INSERT [INTO] tbl_name[(col_name,...)]
SELECT col_name,... FROM tbl_name1
[WHERE ...];
如果不指定字段名,则需要插入的值与表中所有的字段一一对应
示例:
创建数据表sys_employee表结构如下
使用常规方法插入数据
通过第二种方式插入数据
此时创建另一个表用于存放员工的工号和密码,表结构如下
使用SELECT语句插入数据表
删除数据
-- 删除限定条件之内的数据(若不加WHERE条件则会删除表中的所有数据)
DELETE FROM tbl_name [WHERE ...];
-- 清空数据表
TRUNCATE TABLE tbl_name;
使用DELETE删除数据的时候AUTO_INCREMENT属性的初始值不会改变需要使用MODIFY语句进行修改
使用TRUNCATE删除数据时,会直接重置AUTO_INCREMENT的值再次从1开始
删除序号为8的数据,重新修改序号的默认值再插入值时,才能继续按照序号顺序排列
使用TRUNCATE清空数据表,再重新插入数据
可以看到no字段重新从1开始排序
修改数据
UPDATE tbl_name SET col_name = newValue, ... [WHERE ...];
查询数据
单表查询
SELECT [tbl_name|数据表别名.]*|sql_expr [AS 别名] FROM [db_name.]tbl_name [AS 别名] WHERE ...
- 使用通配符
*
查询数据表中所有的字段 - 无论是数据表还是检索的字段都可以起别名,用来标识
- 对于查询的数据表可以在表名前加所在的数据库的库名,这种操作可以在不切换数据库的情况下访问其他数据库的数据表
WHERE查询条件
筛选条件 | 描述 |
---|---|
比较运算符 | > >= < <= != <> <=> = <=>和=的区别在于<=>可以检测NULL值 |
判断字段是否为空 | IS NULL 或 IS NOT NULL |
范围集合 | [NOT] BETWEEN A AND B |
指定集合 | [NOT] IN (…) |
逻辑判断 | AND 逻辑与 OR 逻辑或 |
匹配字符 | [NOT] LIKE ‘…’ |
示例:
当前sys_employee表数据有:
查询数据表中部门为NULL的数据
检测字段是否为NULL可以使用<=>和IS NULL而直接使用department = NULL是检索不到结果的。
范围查询,查询年龄在20-30岁间的员工
既可以使用BETWEEN也可使用比较运算符进行限制。
多表联查
除了单表查询,还可以进行多个表的联合查询,多表联查主要有三种方式:
- 笛卡尔积查询
- 内链接查询
- 外链接查询
创建3个关联表
对应表插入数据
INSERT INTO sys_employee (no, empId, name, age, sex, salary, department, city) VALUES (DEFAULT, 'SOO1', 'Mary', 30, '女', 34000, 1, 1);
INSERT INTO sys_employee (no, empId, name, age, sex, salary, department, city) VALUES (DEFAULT, 'SOO2', 'Tom', 25, '女', 30000, 1, 2);
INSERT INTO sys_employee (no, empId, name, age, sex, salary, department, city) VALUES (DEFAULT, 'SOO3', 'Jack', 34, '男', 20000, 1, 3);
INSERT INTO sys_employee (no, empId, name, age, sex, salary, department, city) VALUES (DEFAULT, 'SOO4', 'Mary1', 50, '女', 34000, 2, 4);
INSERT INTO sys_employee (no, empId, name, age, sex, salary, department, city) VALUES (DEFAULT, 'SOO5', 'Tom1', 22, '女', 30000, 2, 5);
INSERT INTO sys_employee (no, empId, name, age, sex, salary, department, city) VALUES (DEFAULT, 'SOO6', 'Jack1', 33, '男', 20000, 3, 6);
INSERT INTO tb_department (name) VALUES ('研发部');
INSERT INTO tb_department (name) VALUES ('市场部');
INSERT INTO tb_department (name) VALUES ('销售部');
INSERT INTO tb_department (name) VALUES ('产品部');
INSERT INTO tb_city (name) VALUES ('北京');
INSERT INTO tb_city (name) VALUES ('上海');
INSERT INTO tb_city (name) VALUES ('南京');
INSERT INTO tb_city (name) VALUES ('江苏');
笛卡尔积查询用两个表相互关联,用一条记录匹配另一个的所有依次匹配,效果较差,一般不使用这种查询方式。
内联查询:
通过两个表的关联字段sys_employee中的department和tb_department中的id字段相互关联可以得到查询结果。对于内联查询
如果存在找不到对应的数据,就不会再显示在查询结果中,例如:
所以使用INNER JOIN就是采用两个表的交集
外链接查询:
外链接包括两种形式,左链接和右链接。左链接则以左侧的表为主,如果在右表中找不到对应的值则用NULL来表示,右链接相反。
针对于这种无法产生对应值的数据也被称为脏数据,一般会在表中加入外键来防止脏数据的插入
特殊形式的查询
子查询
子查询主要是在条件约束中加入另一个查询结果作为条件,主要形式包含一下几种:
- IN条件子句查询
- 逻辑条件子句查询
- EXISTS条件子句查询
- ANY SOME ALL子句查询
创建学生成绩表(tb_student)和学生评级表(tb_grade)
CREATE TABLE IF NOT EXISTS tb_student (
stuId VARCHAR(4) PRIMARY KEY,
stuName VARCHAR(10) NOT NULL,
score INT
)ENGINE = innoDB;
CREATE TABLE IF NOT EXISTS tb_grade (
grade CHAR(1) PRIMARY KEY,
score INT
)ENGINE = innoDB;
INSERT INTO tb_student (stuId, stuName, score) VALUES ('S001', 'Jack1', 95);
INSERT INTO tb_student (stuId, stuName, score) VALUES ('S002', 'Jack2', 87);
INSERT INTO tb_student (stuId, stuName, score) VALUES ('S003', 'Jack3', 65);
INSERT INTO tb_student (stuId, stuName, score) VALUES ('S004', 'Jack4', 50);
INSERT INTO tb_student (stuId, stuName, score) VALUES ('S005', 'Jack5', 78);
INSERT INTO tb_student (stuId, stuName, score) VALUES ('S006', 'Jack6', 97);
INSERT INTO tb_student (stuId, stuName, score) VALUES ('S007', 'Jack7', 90);
INSERT INTO tb_student (stuId, stuName, score) VALUES ('S008', 'Jack8', 84);
INSERT INTO tb_grade (grade, score) VALUES ('A', 90);
INSERT INTO tb_grade (grade, score) VALUES ('B', 80);
INSERT INTO tb_grade (grade, score) VALUES ('C', 70);
INSERT INTO tb_grade (grade, score) VALUES ('D', 60);
查询学生表中刚好到达评级分数的数据,就可以使用IN子句查询:
查询学生表中成绩评价为B的学生成绩:
EXISTS主要用于判断数据是否存在若存在则继续执行,若不存在则不执行
ANY SOME ALL的区别
运算符 | ANY | SOME | ALL |
---|---|---|---|
> >= | 最小值 | 最小值 | 最大值 |
< <= | 最大值 | 最大值 | 最小值 |
= | 任意值 | 任意值 | |
!= <> | 任意值 |
查询学生成绩在评级中最低值和最大值以上的学生
联合查询
联合查询是将多个表的数据汇总在一起进行查询,通过关键字UNION和UNION ALL来连接多个表
例如:查看员工表和学生表的所有姓名
而使用UNION ALL的结果为
UNION 连接时会自动去除重复的内容,UNION ALL则会将所有内容打印出来
GROUP BY分组
把值相同放到一个组中,最终查询出的结果只会显示组中一条记录,分组配合GROUP_CONCAT()查看组中某个字段的详细信息。
SELECT sql_expr FROM tbl_name GROUP BY col_name;
通过对性别进行分组查询,并查询分组中包含的员工名称
在进行分组时还有5种聚合函数配合分组查询
- COUNT(*):计数,对分组的记录数进行统计,参数可以使用*或者字段名称,需要注意的是如果使用字段名称是无法检测NULL值的
- SUM(col_name):求和,对分组记录中的字段进行求和
- MAX(col_name):求最大值,查询分组中字段的最大值
- MIN(col_name):求最小值,查询分组中字段的最小值
- AVG(col_name):求平均值,对分组记录中的字段求平均值
在语句最后如果加上WITH ROLLUP则会将以上结果进行汇总
在GROUP BY语句中使用HAVING关键字可以再对分组结果进行筛选,例如:
ORDER BY排序
SELECT * FROM tbl_name ORDER BY col_name ASC|DESC;
ORDER BY排序的关键字主要是ASC顺序排序和DESC倒序排序
如果不书写排序方式则默认按顺序排列
LIMIT限制结果查询数量
SELECT * FROM tbl_name LIMIT row_count;
SELECT * FROM tbl_name LIMIT offset, row_count;
第一种语句直接返回数据表中的前多少条,第二种语句带有偏移量,查询从偏移量开始之后的多少条,偏移量从0开始
外键约束
外键约束在建表时的创建
只有在使用InnoDB的存储引擎时才能使用外键。
删掉上文描述的员工信息表和部门表,重新创建包含外键的数据表。以部门表(tb_department)为父表,员工表(tb_employee)为子表,子表的depId字段作为外键关联父表的depId。
查看部门表的表结构:
查看员工表的建表语句与表结构:
由系统给出的建表语句可以看出,对于创建的外键的字段会自动创建一个空索引,而且也会给外键一个默认的名称,子表的外键字段和主表的主键字段类型要相似;如果是数值型要求一致,并且无符号也要一致;如果是字符型,要求类型一致,长度可以不同,同时子表的外键必须是主表的主键。
先插入一些有效数据:
INSERT INTO tb_department (depId, depName) VALUES (1, '研发部');
INSERT INTO tb_department (depId, depName) VALUES (2, '市场部');
INSERT INTO tb_department (depId, depName) VALUES (3, '销售部');
INSERT INTO tb_department (depId, depName) VALUES (4, '产品部');
INSERT INTO tb_employee(empId, name, depId) VALUES ('S001', 'Jack', 1);
INSERT INTO tb_employee(empId, name, depId) VALUES ('S002', 'Mary', 2);
INSERT INTO tb_employee(empId, name, depId) VALUES ('S003', 'Tom', 3);
要先插入主表,再插入子表
- 如果子表中有对应主表的值,则主表的记录不能被删除或更新
- 不能向子表中插入外键不在主表中的值
- 不能更新子表外键为主表中不存在的值
对于以上三种情况数据库都会报
动态创建外键和删除外键
ALTER TABLE tbl_name ADD [CONSTRAINT 外键名称] FOREIGN KEY (外键字段) REFERENCES 主表名(主表关联字段);
ALTER TABLE tbl_name DROP FOREIGN KEY 外键名称;
在动态创建外键时要求子表中不能存在脏数据,否则不能创建外键
外键约束的参照要求
- CASCADE:从主表中删除或更新数据时,子表对应的外键也会自动删除或更新
- SET NULL:从主表中删除或更新数据时,可以设置子表的值为NULL
- NO ACTION | RESTRICT:拒绝对主表进行删除和更新操作
删除原来的员工表,重新建立是得更新或删除主表时子表也会自动更新或删除
CREATE TABLE IF NOT EXISTS tb_employee
(
empId VARCHAR(4) NOT NULL,
name VARCHAR(10) DEFAULT NULL,
depId TINYINT DEFAULT NULL,
PRIMARY KEY (empId),
KEY depId (depId),
CONSTRAINT depId_fk_dep FOREIGN KEY (depId) REFERENCES tb_department (depId)
ON UPDATE CASCADE
ON DELETE CASCADE
) ENGINE = InnoDB;
INSERT INTO tb_employee(empId, name, depId) VALUES ('S001', 'Jack', 1);
INSERT INTO tb_employee(empId, name, depId) VALUES ('S002', 'Mary', 2);
INSERT INTO tb_employee(empId, name, depId) VALUES ('S003', 'Tom', 3);
重新插入数据后,更新或删除主表的值可以看到子表也会跟着变化