插入操作
INSERT INTO 表名 (列名1,列名2…) VALUES(列值1,列值2…);
注意:列名与列值的类型、个数、顺序要一一对应。
可以把列名当做java中的形参,把列值当做实参。
参不要超出列定义的长度。
如果插入空值,请使用null
插入的日期和字符一样,都使用引号括起来。
- INSERT INTO emp(id,name,gender) VALUES(1,’zhangsan’,’female’);
修改操作
UPDATE 表名 SET 列名1=列值1,列名2=列值2…WHERE 列名=值
1.UPDATE emp SET saraly=5000
2.UPDATE emp SET saraly=3000 WHERE name='zs'
3.UPDATE emp SET saraly=4000,job='ccc' WHERE name='aaa'
4.UPDATE emp SET saraly=saraly+1000 WHERE name='wu'
删除操作
DELETE FROM 表名 [WHERE 列名=值]
DELETE emp WHERE name='zs'
查询操作
基础查询
查询所有列
SELECT * FROM emp;
查询指定咧
SELECT sid,sname FROM emp;
条件查询
条件查询就是在查询时给出WHERE子句,在WHERE子句中可以使用如下运算符及关键字:
=、!=、<>、<、<=、>、>=;
BETWEEN…AND;
IN(set);
IS NULL;
AND;OR;NOT;
查询性别为女,并且年龄为50的记录
SELECT * FROM stu WHERE gender='female' and age=50;
查询学号为S_1001,或者姓名为lisi的记录
SELECT * FROM stu WHERE sid='s_1001' OR sname='lisi';
查询学号为S_1001,S_1002,S_1003的记录
SELECT * FROM stu WHERE sid IN ('s_1001','s_1002','s_1003')
查询学号不是S_1001,S_1002,S_1003的记录
SELECT * FROM stu WHERE sin NOT IN ('s_1001','s_1002','s_1003')
查询年龄为null的记录
SELECT * FROM stu WHERE age IS NULL;
查询年龄在20到40之间的学生记录
SELECT * FROM stu WHERE age BWTEEN 20 AND 40;
查询性别非男的学生记录
SELECT * FROM stu WHERE gender!='male' SELECT * FROM stu WHERE gender<>'male' SELECT * FROM stu WHERE NOT gender='male'
查询姓名不为null的学生记录
SELECT * FROM stu WHERE sname IS NOT NULL
模糊查询
需要使用关键字LIKE
通配符:_ :任意一个字母;%:任意0~n个字母
查询姓名由5个字母构成的学生记录
SELECT * FROM stu WHERE sname LIKE '_____'
查询姓名由5个字母构成,并且第5个字母为“i”的学生记录
SELECT * FROM stu WHERE sname LIKE '____i'
查询姓名以“z”开头的学生记录
SELECT * FROM stu WHERE sname LIKE 'z%'
查询姓名中第2个字母为“i”的学生记录
SELECT * FROM stu WHERE sname LIKE '_i%'
查询姓名中包含“a”字母的学生记录
SELECT * FROM stu WHERE sname LIKE '%a%'
字段控制查询
去除重复记录
SELECT DINSTINCT sal FROM emp;
查看雇员的月薪与佣金之和(都是数值类型才能进行运算)
SELECT *,sal+comm FROM emp
下面使用了把NULL转换成数值0的函数IFNULL
SELECT *,sal+IFNULL(comm,0) FROM emp
给列名添加别名,其中AS可以省略
SELECT *,sal+IFNULL(comm,0) AS total FROM emp
排序
查询所有学生记录,按年龄升序排序(默认ASC)
SELECT * FROM stu ORDER BY age ASC
查询所有学生记录,按年龄降序排序
SELECT * FROM stu ORDER BY age DESC
查询所有雇员,按月薪降序排序,如果月薪相同时,按编号升序排序
SELECT * FROM emp WHERE ORDER BY sal DESC,empno ASC;
聚合函数是用来做纵向运算的函数 sum avg max min count
- COUNT():统计指定列不为NULL的记录行数
- MAX():计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算
- MIN():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算
- SUM():计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0
AVG():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0
查询emp表中记录数:
SELECT COUNT(*) AS cnt FROM emp
查询emp表中有佣金的人数:
SELECT COUNT(comm) AS cnt FROM emp
查询emp表中月薪大于2500的人数:
SELECT COUNT(*) AS cnt FROM emp WHERE sal>2500
统计月薪与佣金之和大于2500元的人数:
SELECT COUNT(*) AS cnt FROM emp WHERE sal+IFNULL(comm,0)>2500
查询有佣金的人数,以及有领导的人数:
SELECT COUNT(comm),COUNT(manager) cnt FROM emp;
查询所有雇员月薪和:
SELECT SUM(sal) FROM emp
查询所有雇员月薪和,以及所有雇员佣金和:
SELECT SUM(sal),SUM(comm) FROM emp
查询所有雇员月薪+佣金和:
SELECT SUN(sal+IFNULL(comm,0)) FROM emp
统计所有员工平均工资:
SELECT AVG(*) FROM emp
查询最高工资和最低工资:
SELECT MAX(sal),MIN(sal) FROM emp
分组查询,关键字GROUP BY、HAVING、LIMIT
凡是聚合函数同时出现的列名,则一定要写在group by之后
查询每个部门的部门编号和每个部门的工资和:
SELECT deptno,SUM(sal) FROM emp GROUP BY deptno
查询每个部门的部门编号以及每个部门的人数:
SELECT deptno,count(*) FROM emp GROUP BY deptno
查询每个部门的部门编号以及每个部门工资大于1500的人数:
SELECT deptno,COUNT(*) FROM emp WHERE sal>1500 GROUP BY deptno
查询工资总和大于9000的部门编号以及工资和:
SELECT deptno,SUM(sal) FROM emp GROUP BY deptno HAVING SUM(sal)>9000
注:having与where的区别: 1.having是在分组后对数据进行过滤. where是在分组前对数据进行过滤 2.having后面可以使用分组函数(统计函数) where后面不可以使用分组函数。
查询5行记录,起始行从0开始,即第一行开始
SELECT * FROM emp LIMIT 0,5
查询10行记录,起始行从3开始
SELECT * FROM emp LIMIT 3,10
分页查询,如果一页记录为10条,希望查看第3页记录应该怎么查呢?
- 第一页记录起始行为0,一共查询10行;
- 第二页记录起始行为10,一共查询10行;
第三页记录起始行为20,一共查询10行;
SELECT * FROM emp LIMIT (n-1)*m,m
查询语句书写顺序:select – from- where- group by- having- order by-limit
- 查询语句执行顺序:from - where -group by - having - select - order by-limit
数据的完整性
作用:保证用户输入的数据保存到数据库中是正确的。
确保数据的完整性 = 在创建表时给表中添加约束
实体完整性
- 实体:即表中的一行(一条记录)代表一个实体(entity)
实体完整性的作用:标识每一行数据不重复。
主键约束(primary key)
每个表中要有一个主键
特点:数据唯一,且不能为null
第一种添加方式
CREATE TABLE student( id int primary key, name varchar(50) );
第二种添加方式:此种方式优势在于,可以创建联合主键
CREATE TABLE student( id int, name varchar(50), primary key(id) ); CREATE TABLE student( classid int, stuid int, name varchar(50), primary key(classid,stuid) );
第三种添加方式:
CREATE TABLE student( id int, name varchar(50) ); ALTER TABLE student ADD PRIMARY KEY (id);
唯一约束(unique)数据不能重复
CREATE TABLE student(
Id int primary key,
Name varchar(50) unique
);
自动增长列(auto_increment)
给主键添加自动增长的数值,列只能是整数类型
CREATE TABLE student(
Id int primary key auto_increment,
Name varchar(50)
);
INSERT INTO student(name) values(‘tom’);
域完整性
限制此单元格的数据正确,不对照此列的其它单元格比较
数据类型:(数值类型、日期类型、字符串类型)
非空约束:not null
CREATE TABLE student(
Id int pirmary key,
Name varchar(50) not null,
Sex varchar(10)
);
INSERT INTO student values(1,’tom’,null);
默认值约束 default
CREATE TABLE student(
Id int pirmary key,
Name varchar(50) not null,
Sex varchar(10) default ‘男’
);
insert into student1 values(1,'tom','女');
insert into student1 values(2,'jerry',default);
引用完整性(参照完整性)外键约束:FOREIGN KEY
例:
CREATE TABLE student(
sid int pirmary key,
name varchar(50) not null,
sex varchar(10) default ‘男’
);
create table score(
id int,
score int,
sid int , -- 外键列的数据类型一定要与主键的类型一致
CONSTRAINT fk_score_sid foreign key (id) references student(sid)
);
第二种添加外键方式。
ALTER TABLE score1 ADD CONSTRAINT fk_stu_score FOREIGN KEY(id) REFERENCES student(sid);
表与表之间的关系
图片:
多表查询
合并结果集
把两个select语句的查询结果合并到一起
UNION:去除重复记录,例如:
SELECT * FROM t1 UNION SELECT * FROM t2
图片:
UNION ALL:不去除重复记录,例如:
SELECT * FROM t1 UNION ALL SELECT * FROM t2
图片:
要求:被合并的两个结果:列数、列类型必须相同
连接查询
连接查询就是求出多个表的乘积,即产生笛卡尔积,例如t1连接t2,那么查询出的结果就是t1*t2
图片:
- 那么多表查询产生这样的结果并不是我们想要的,那么怎么去除重复的,不想要的记录呢,当然是通过条件过滤。通常要查询的多个表之间都存在关联关系,那么就通过关联关系(主外键)去除笛卡尔积。
图片:
图片:
使用主外键关系作为条件来去除无用信息
SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno;
图片:
内连接
上面的连接语句就是内连接,但它不是SQL标准中的查询方式,可以理解为方言。标准内连接如下:
SELECT * FROM emp e INNER JOIN dept d ON e.deptno=d.deptno
外连接
特点:查询出的结果存在不满足条件的可能
左连接:
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.deptno=d.deptno
左连接是先查询出左表(即以左表为主),然后查询右表,右表中满足条件的显示出来,不满足条件的显示NULL。
这么说可能不太明白,还是用上面的例子来说明。其中emp表中“张三”这条记录中,部门编号为50,而dept表中不存在部门编号为50的记录,所以“张三”这条记录,不能满足e.deptno=d.deptno这条件。但在左连接中,因为emp表是左表,所以左表中的记录都会查询出来,即“张三”这条记录也会查出,但相应的右表部分显示NULL。
图片:
- 右连接
右连接就是先把右表中所有记录都查询出来,然后左表满足条件的显示,不满足显示NULL。例如在dept表中的40部门并不存在员工,但在右连接中,如果dept表为右表,那么还是会查出40部门,但相应的员工信息为NULL。
SELECT * FROM emp e RIGHT OUTER JOIN dept d ON e.deptno=d.deptno
图片:
连接心得
- 连接不限与两张表,连接查询也可以是三张、四张,甚至N张表的连接查询。通常连接查询不可能需要整个笛卡尔积,而只是需要其中一部分,那么这时就需要使用条件来去除不需要的记录。这个条件大多数情况下都是使用主外键关系去除。
两张表的连接查询一定有一个主外键关系,三张表的连接查询就一定有两个主外键关系
自然连接
连接查询会产生无用笛卡尔积,我们通常使用主外键关系等式来去除它。而自然连接无需你去给出主外键等式,它会自动找到这一等式
两张连接的表中名称和类型完全一致的列作为条件,例如emp和dept表都存在deptno列,并且类型一致,所以会被自然连接找到.
当然自然连接还有其他的查找条件的方式,但其他方式有可能存在问题SELECT * FROM emp NATURAL JOIN dept; SELECT * FROM emp NATURAL LEFT JOIN dept; SELECT * FROM emp NATURAL RIGHT JOIN dept;
子查询
子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个,或两个以上SELECT,那么就是子查询语句了
- 子查询出现的位置:
- where后,作为被查询的条件的一部分
- from后,作表
- 当子查询出现在where后作为条件时,还可以使用如下关键字:
- any
- all
- 子查询结果集的形式
- 单行单列(用于条件)
- 单行多列(用于条件)
- 多行多列(用于条件)
- 多行多列(用于表)
样例
- 工资高于JONES的员工
分析:查询条件:工资>JONES工资,其中JONES工资需要一条子查询
第一步:查询JONES的工资
SELECT sal FROM emp WHERE ename='JONES'
第二步:查询高于JONES工资的员工
SELECT * FROM emp WHERE sal>(第一步)
合并:
SELECT * FROM emp WHERE sal>(SELECT sal FROM emp WHERE ename='JONES')
- 查询与SCOTT同一个部门的员工
分析:先查询SCOTT的部门,作为子查询,再让其作为条件查询同一个部门的员工 工资高于30号部门所有人的员工信息
分析:查询条件:工资高于30部门所有人工资,其中30部门所有人工资是子查询。高于所有需要使用all关键字。SELECT * FROM emp WHERE sal>(SELECT MAX(sal) FROM emp WHERE deptno=30);
第一步:查询30部门所有人工资
SELECT sal FROM emp WHERE deptno=30
第二步:查询高于30部门所有人工资的员工信息
SELECT * FROM emp WHERE sal>ALL(第一步)
结果:
SELECT * FROM emp WHERE sal>ALL(SELECT sal FROM emp WHERE deptno=30)
- 子查询作为条件
子查询形式为多行单列(当子查询结果集形式为多行单列时可以使用ALL或ANY关键字)
- 查询工作和工资与MARTIN完全相同的员工信息
分析:
查询条件:工作和工资与MARTIN完全相同,这是子查询
- 查询工作和工资与MARTIN完全相同的员工信息
第一步:查询出MARTIN的工作和工资
SELECT job,sal FROM emp WHERE ename='MARTIN'
第二步:查询出与MARTIN工作和工资相同的人
SELECT * FROM emp WHERE (job,sal) IN (第一步)
结果:
SELECT * FROM emp WHERE (job,sal) IN (SELECT job,sal FROM emp WHERE ename='MARTIN')
5. 有2个以上直接下属的员工信息
SELECT * FROM emp WHERE empno IN(SELECT mgr FROM emp GROUP BY mgr HAVING COUNT(mgr)>=2);
1. 子查询作为条件
2. 子查询形式为单行多列
- 查询员工编号为7788的员工名称、员工工资、部门名称、部门地址
分析:(无需子查询)
查询列:员工名称、员工工资、部门名称、部门地址
查询表:emp和dept,分析得出,不需要外连接(外连接的特性:某一行(或某些行)记录上回出现一半有值,一半为NULL值)
条件:员工编号为7788
第一步:去除多表,只查一张表,这里去除部门表,只查员工表
SELECT ename,sal FROM emp e WHERE empno=7788
第二步:让第一步与dept做内连接查询,添加主外键条件去除无用笛卡尔积
SELECT e.ename,e.sal,d.dname,d.loc FROM emp e,dept d WHERE e.deptno=d.deptno AND empno=7788
第二步中的dept表表示所有行所有列的一张完整的表,这里可以把dept替换成所有行,但只有dname和loc列的表,这需要子查询。
第三步:查询dept表中dname和loc两列,因为deptno会被作为条件,用来去除无用笛卡尔积,所以需要查询它。
SELECT dname,loc,deptno FROM dept
第四步:替换第二步中的dept
SELECT e.ename, e.sal, d.dname, d.loc FROM emp e, (SELECT dname,loc,deptno FROM dept) d WHERE e.deptno=d.deptno AND e.empno=7788
* 子查询作为表
* 子查询形式为多行多列
自连接:自己连接自己,起别名
求7369员工编号、姓名、经理编号和经理姓名
SELECT e1.empno , e1.ename,e2.mgr,e2.ename FROM emp e1, emp e2 WHERE e1.mgr = e2.empno AND e1.empno = 7369;
MySQL数据库的备份与恢复
生成SQL脚本,导出数据
在控制台使用mysqldump命令可以用来生成指定数据库的脚本文本,但要注意,脚本文本中只包含数据库的内容,而不会存在创建数据库的语句!所以在恢复数据时,还需要自已手动创建一个数据库之后再去恢复数据。
mysqldump –u用户名 –p密码 数据库名>生成的脚本文件路径
图片:
执行SQL脚本,恢复数据
前提:必须先创建数据库名
执行SQL脚本需要登录mysql,然后进入指定数据库,才可以执行SQL脚本!!!
执行SQL脚本不只是用来恢复数据库,也可以在平时编写SQL脚本,然后使用执行SQL 脚本来操作数据库!大家都知道,在黑屏下编写SQL语句时,就算发现了错误,可能也不能修改了。所以建议使用脚本文件来编写SQL代码,然后执行之!
SOURCE C:\mydb1.sql
图片:
还可以通过下面的方式来执行脚本文件(这种方式无需登录mysql!):
mysql -uroot -p123 mydb1