数据的操作
1、插入数据,
1.1单条记录插入:
insert into 表名(字段1, 字段2, 字段3, ……)
values(值1,值2,值3,…);
1.2 批量记录插入:
insert into 表名(字段1, 字段2, 字段3, ……)
values(值11,值21,值31,…),
(值12,值22,值32,…),
……;
2、更新数据。
2.1 更新所有数据
update 表名 set 字段1=值1,字段2=值2, 字段3=值
2.2更新特定数据记录:
update 表名set 字段1=值1,字段2=值2, 字段3=值3,
……where 条件;
3、删除数据。
3.1 删除特定数据
delete from表名 where 条件;
3.2 删除所有数据
delete from 表名;
单表数据记录查询
1、简单数据查询,
1.1 查询所有字段 select * from 表名
1.2 查询指定字段 select 字段 …… from 表名
1.3 避免重复数据查询 select distinct 字段… from 表名
1.4 实现数字四则运算数据查询(+,-,*,/,%)
select 字段 运算符 运算符操作数… from 表名
1.5设置显示格式数据查询 CONCAT()
select 字段 [as] 字符串 from 表名
select CONCAT(字段 字符串 … ) from 表名
例:select CONCAT(name, ‘––>’, score) from student
2、条件数据记录查询
select 字段 …… from 表名 where 条件
mysql 支持的比较运算符和逻辑运算符
>,<,=,!=,>=,<=, AND(&&) ,OR(||),XOR(异或),NOT(!)
2.1 单条件数据查询:
select 字段 …... from 表名 where 条件
2.2 多条件数据查询:
select 字段 …... from 表名 where 条件1 AND 条件2....
2.3 带 between and 关键字的范围查询;
select 字段 …... from 表名 where字段 between 值1 AND 值2
2.4 不符合范围的数据记录查询
select 字段 …... from 表名 where字段 not between 值1 AND 值2
2.5 带 IS NULL的关键字的空值查询
select 字段 …... from 表名 where 字段名 is null;
2.6 非空记录查询
select 字段 …... from 表名 where 字段名 is not null;
2.7 带 IN 关键字的集合查询:
select 字段 …... from 表名 where 字段名 in (值1,值2, …...)
2.8 不在集合中数据记录查询:
select 字段 …... from 表名 where 字段名 not in (值1,值2, …...)
2.9 带 LIKE 关键字的模糊查询;
select 字段 …... from 表名 where 字段名 like 值1
LIKE 关键字支持的通配符
“_” : 通配单个字符;
“%”: 通配任意字符,可以是0个字符,1个字符,或多个字符
- 排序查询:
select 字段 …… from 表名 ORDER BY 字段名 ASC | DESC
ASC 表明升序 DESC 表明降序 - 分组查询:
select 字段 …… from 表名 [WHERE 条件] group BY 字段名
分组后结果再进行条件过滤则必须使用having 字句:
select 字段 …… from 表名 [WHERE 条件] group BY 字段名 having 条件
说明:
分组查询(GROUP BY)一般和聚合函数(统计函数)一起使用,如果查询的字段出现在
GROUP BY后,却没有包含在聚合函数中,SQL语句很有可能会报错.
例子: 1. 通过部门分组后,获取每个部门的人数,
select count(name) from fruit group by dept;
2. 还可以在分组后设置条件过滤,要求统计部门人数时,该部门人数要>1
select count(name) from fruit group by dept having count(name)>1;
3. 如果想获取分组后部门人员组成,可使用 group_concat函数
select group_concat(name) from fruit group by dept;
- 排序查询:
select 字段 …… from 表名 ORDER BY 字段名 ASC | DESC
ASC 表明升序 DESC 表明降序 - 分组查询:
select 字段 …… from 表名 [WHERE 条件] group BY 字段名
分组后结果再进行条件过滤则必须使用having 字句:
select 字段 …… from 表名 [WHERE 条件] group BY 字段名 having 条件
说明:
分组查询(GROUP BY)一般和聚合函数(统计函数)一起使用,如果查询的字段出现在
GROUP BY后,却没有包含在聚合函数中,SQL语句很有可能会报错.
例子: 1. 通过部门分组后,获取每个部门的人数,
select count(name) from fruit group by dept;
2. 还可以在分组后设置条件过滤,要求统计部门人数时,该部门人数要>1
select count(name) from fruit group by dept having count(name)>1;
3. 如果想获取分组后部门人员组成,可使用 group_concat函数
select group_concat(name) from fruit group by dept;
-
聚合函数查询:
COUNT函数:统计记录行的总数
select count(字段名) from 表名
注意:如果字段名为 *,计算表中的总行数,不管某字段是否为NULL
如果指定了具体字段名,会忽略空值的行SUM函数:统计某列数据的和
select sum(字段名) from 表名
AVG函数:统计某列数据的平均值
select avg(字段名) from 表名
MAX函数:统计某列数据的最大值
select max(字段名) from 表名
MIN函数:统计某列数据的最小值
select min(字段名) from 表名
多表连接查询
-
内连接:
又称为简单连接,或者自然连接,是一种常见的连接查询.内连接使
用比较运算符,对两个表中的数据,进行比较,并列出与连接条件匹
配的数据行,组合成新的记录。
在内连接查询中,只有满足条件的记录,才会出现在查询结果中.
简单理解:返回表1和表2同时满足条件的记录。语法格式
SELECT 查询字段 FROM 表1 [INNER] JOIN 表2 ON
表1.关系字段=表2.关系字段;例子:两个表联合查询
select 字段名… FROM 表1 INNER JOIN 表2 ON 条件;
多个表查询时,可使用:
select 字段名… FROM 表1 INNER JOIN 表2 ON 条件
INNER JOIN 表3 ON 条件; -
外连接:
内连接查询,返回的结果,只包含符合查询条件和连接条件的数据
有时需要返回的查询结果,不仅包含符合条件的数据,而且,包括左
表和右表中的所有数据,此时,需要使用外连接.2.1 左外连接
以左边的表为主,在右边的表中找到所有满足条件的元素,并 把他们连接起来,如果没有对应的元素,则在相应位置上的值
为null。
select 字段名… FROM 表1 LEFT JOIN 表2 ON 条件;2.2 右外连接
与左外连接相反,以右边的表为主,在左边的表中找到所有满
足条件的元素,并把他们连接起来,如果没有对应的元素,则
在相应位置上的值为null。
select 字段名… FROM 表1 RIGHT JOIN 表2 ON 条件;
SQL语句的执行顺序
子查询
子查询是指一个查询语句嵌套在另一个查询语句内部的查询,在select子句中先计算子查询,子查询结果作为外层另一个查询的条件,查询可以基于一个表或者多个表.
子查询中常用的操作符有 ANY(SOME),ALL,IN,EXISTS,子查询可以添加到select,update,delete语句中,而且可以进行多层嵌套。子查询也可以使用比较运算符如“<,>,<=,>=,!=,=”等。
- 带有ANY(SOME)关键字的子查询:
它允许创建一个表达式,对子查询的返回值列表,进行比较,只要满
足内层子查询中的,任意一个比较条件,就返回一个结果作为外层查
询条件。
例子:
select 字段名… FROM 表 where 字段>ANY(select 字段名… FROM 表);
- 带有ALL关键字的子查询:
ALL与ANY不同,表示同时满足所有内层查询的条件,
例子:
select 字段名… FROM 表where 字段>ALL(select 字段名… FROM 表);
- 带有EXISTS关键字的子查询:
EXISTS后面的参数,可以是任意一个子查询,这个子查询的作用相当
于测试,它不产生任何数据,只返回TRUE或FALSE.当返回值为TRUE
时,外层的查询才会执行,
例子:
select 字段名… FROM 表where EXISTS (select 字段… FROM 表);
只有在蓝色部分的子查询存在结果时,才去执行外层红色部分的查询
4. 带有IN关键字的子查询:
使用IN关键字,进行子查询时,内层查询语句返回一个数据列,这个
数据列中的值,将供外层查询语句进行比较操作
例子:
select 字段名… FROM 表where 字段IN (select 字段名… FROM 表);
- 带有比较运算符的子查询:
子查询中,可以使用比较运算符,比如<、>、<=、>=、=、!=等
例子:
select 字段名… FROM 表where 字段= (select 字段… FROM 表);
请注意如果用 = 比较运算符,子查询的结果往往是唯一的。
数据库备份和加载
-
备份数据库:
终端输入:
mysqldump -u root -p 需备份的数据库名 >备份的目的路径 -
将备份文件拷贝到目标主机:
-
目标主机登陆mysql,创建新的数据库:
create database 新的数据库名称
4 导入备份数据:
第一种方法: 终端输入:
mysql -u root -p 新建的数据库名 < 备份文件路径
第二种方法: mysql中执行:
mysql>use 新建的数据库名;
mysql> source 备份文件路径;
案例
######### 多表查询:内连接, 外连接 #################
# 创建部门表
CREATE TABLE dept(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');
SHOW CREATE TABLE dept;
# 创建员工表
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
gender CHAR(1), -- 性别
salary DOUBLE, -- 工资
join_date DATE, -- 入职日期
dept_id INT,
FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键)
);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男',7200,'2013-02-24',1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男',3600,'2010-12-02',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2015-10-07',3);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2011-03-14',1);
/*
外键约束:限制从表插入数据的合理型
如果没有外键约束,不影响业务逻辑上的数据关联关系
*/
# 笛卡尔积查询 --- 导致数据混乱
SELECT * FROM emp, dept;
/*
多表查询分析步骤:
1.查询的数据在哪些表上(涉及那几张表)
2.这些表的关联关系
3.还有哪些筛选条件
4.最后再考虑查询哪些字段
*/
# 多表-- 内连接
# 查询所有员工及其所属部门信息
# 内连接 -- 隐式内连接:where
SELECT * FROM emp, dept WHERE emp.`dept_id` = dept.`id`;
# 内连接 -- 显示内链接:inner join ... on
SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;
SELECT emp.`id`, emp.name emp_name, gender, salary, dept.name dept_name FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;
# 查询猪八戒是那个部门的
SELECT
emp.`id`,
emp.name emp_name,
gender,
salary,
dept.name dept_name
FROM
emp
INNER JOIN dept
ON emp.`dept_id` = dept.`id`
WHERE emp.`NAME` = '猪八戒';
# 方式二
SELECT * FROM emp WHERE NAME='猪八戒';
SELECT * FROM dept;
SELECT t1.*, t2.* FROM (SELECT * FROM emp WHERE NAME='猪八戒') t1
INNER JOIN (SELECT * FROM dept) t2
ON t1.dept_id = t2.id;
# 外连接: 左外连接(left [outer] join...on ), 右外链接(right [outer] join...on )
# 左外和右外可以互相转换,重点掌握左外连接
# 外连接的查询: 主表和从表数据没有管理关系,但要将主要业务逻辑的表数据表数据全部查询出来
# 左外查询:将左表中的数据全部查询出来
# 查询所有员工信息,刚入职没有分配部门的员工也要查询出来
SELECT * FROM emp LEFT JOIN dept ON emp.`dept_id` = dept.`id`;
# 右外查询: 将右表中的数据全部查询出来
SELECT * FROM dept RIGHT JOIN emp ON emp.`dept_id` = dept.`id`;
# 查询所有部门下的员工信息,新成立的部门下没有员工也要查询出来
SELECT * FROM emp RIGHT JOIN dept ON emp.`dept_id` = dept.`id`;
SELECT * FROM dept LEFT JOIN emp ON emp.`dept_id` = dept.`id`;
# 子查询:当前sql需要使用另外一个sql语句查询作为条件,这样的sql语句称为子查询
/*
子查询的思路:
1.子查询的条件是一个单行单列: 使用where的条件判断语句(=,!=, >, >=, < , <=)
2.子查询的条件是多行单列: in , not in, (any, all)
3.子查询的条件是多行多列: 当作一张临时表看待
*/
# 1.子查询的条件是一个单行单列: 使用where的条件判断语句(=,!=, >, >=, < , <=)
# 需求:查询姓名是唐僧员工所属部门
-- 步骤1: select dept_id from emp where name='唐僧';
-- 步骤2: select * from dept where id = 2;
SELECT * FROM dept WHERE id = (SELECT dept_id FROM emp WHERE NAME='唐僧');
# 需求:查询姓名是唐僧员工的信息及其所属部门
SELECT * FROM dept, emp WHERE dept.`id` = emp.`dept_id` AND emp.`NAME`='唐僧';
# 需求:查询工资大于5000的员工来自那个部门
SELECT * FROM (SELECT * FROM emp WHERE salary>5000) t1 LEFT JOIN dept ON t1.dept_id = dept.id;
/*
1. 查询工资大于5000的员工
2. 查询id是1,3,6的员工来自那个部门
*/
# 1. 查询工资大于5000的员工
SELECT * FROM emp WHERE salary>5000;
SELECT dept_id FROM emp WHERE salary>5000;
# 2.子查询的条件是多行单列: in , not in
SELECT dept_id FROM emp WHERE salary>5000;
SELECT * FROM dept WHERE id IN (SELECT dept_id FROM emp WHERE salary>5000);
-- select * from dept where id=1 or id=2 or id=null;
# 3.子查询的条件是多行多列----当作一张临时表看待
SELECT * FROM emp WHERE salary>5000;
-- 查询工资大于5000的员工信息及其所属部门,如果有员工没有分配部门也要查出来
SELECT * FROM (SELECT * FROM emp WHERE salary>5000) t1 LEFT JOIN dept ON t1.dept_id = dept.id;
-- 查询工资大于5000的员工信息及其所属部门
SELECT dept.* FROM (SELECT * FROM emp WHERE salary>5000) t1 INNER JOIN dept ON t1.dept_id = dept.id;
-- 子查询练习:
# 需求:查询大于平均工资的所有员工信息
-- 1. 查询平均工资
SELECT AVG(salary) FROM emp;
-- 2. 根据平均工资查询员工表
SELECT * FROM emp WHERE salary > 5883;
-- 最终的子查询语句
SELECT * FROM emp WHERE salary > (SELECT AVG(salary) FROM emp);
# 需求:查询工资低于平均工资的员工并且员工的入职时间早于2011年
SELECT * FROM emp WHERE salary < (SELECT AVG(salary) FROM emp) AND join_date < '2011-01-01';
# 需求:查询工资大于平均工资的员工并且该员工属于市场部门
-- 方式1
SELECT * FROM
(SELECT * FROM emp WHERE salary > (SELECT AVG(salary) FROM emp)) t1,
dept
WHERE t1.dept_id = dept.id AND dept.`NAME`='市场部';
-- 方式2 : 先查询员工和部门的对应关系表,然后在表中筛选需要的数据
SELECT t1.* FROM
(SELECT emp.*, dept.`NAME` 部门 FROM emp, dept WHERE emp.`dept_id` = dept.`id`) t1
WHERE t1.salary > (SELECT AVG(salary) FROM emp) AND t1.部门='市场部';
-- 方式3 : 先查询名称是市场部门的id, 再根据这个id,和平均工资筛选员工表
SELECT emp.*, (SELECT NAME FROM dept WHERE id = emp.`dept_id`)
FROM emp
WHERE salary>(SELECT AVG(salary) FROM emp)
AND emp.`dept_id`=(SELECT id FROM dept WHERE NAME='市场部')
# 子查询: any, all,
# any :表示满足子查询结果中的任意一个
SELECT * FROM emp WHERE salary > ANY(SELECT salary FROM emp WHERE salary >=4500);
SELECT * FROM emp WHERE salary < ANY(SELECT salary FROM emp WHERE salary >=4500);
SELECT salary FROM emp WHERE salary >=4500;
SELECT * FROM emp;
# all: 表示满足子查询结果中的所有
SELECT * FROM emp WHERE salary > ALL(SELECT salary FROM emp WHERE salary >=4500);
SELECT * FROM emp WHERE salary < ALL(SELECT salary FROM emp WHERE salary >=4500);
/*
EXISTS : 相当于开关,当EXISTS后面小括号内查询有结果表示真,当没有结果表示假
如果为真,就执行第二步查询语句
如果为假,就不执行第二步查询语句
*/
SELECT * FROM emp WHERE EXISTS(SELECT salary FROM emp WHERE salary >=14500);