MySQL增删改查
1.SQL语句分类
- DDL(Data Definition Language):数据定义语言,用来新建数据库,新建表。
- DML(Data Manipulation Language):数据操作语言,对数据库中的表内容进行新增、修改、删除。
- DCL(Data Control Language):数据控制语言,用来修改数据库的事务,密码,用户权限。
- DQL(Data Query Language):数据查询语言,用来数据库中的表内容。
2.DDL操作数据库
创建一个数据库
sql SQL> CREATE DATABASE mydb1;
创建一个GBK样式的数据库
sql SQL> CREATE DATABASE mydb2 character SET GBK;
创建一个utf-8样式的数据库和排列顺序
SQL> CREATE DATABASE mydb3 character SET utf8 COLLATE utf8_general_ci;
查看当前数据库服务器中的所有数据库
SQL> SHOW DATABASES;
查看前面创建的mydb2数据库的定义信息
SQL> Show CREATE DATABASE mydb2;
查看服务器中的数据库,并把mydb2的字符集修改为utf8;
SQL> ALTER DATABASE mydb2 character SET utf8;
注意:修改完数据库字符集,需要重启mysql数据库,这个修改只能对新表有用,修改之前已经存在的无用。
删除mydb3
SQL> DROP DATABASE mydb3;
查看当前使用的数据库
SQL> Select database();
切换数据库
SQL> USE mydb2;
3.DDL操作表
新建表
SQL> CREATE TABLE Employees
(
id INT NOT NULL,
age INT NOT NULL,
first VARCHAR(255),
last VARCHAR(255),
PRIMARY KEY ( id )
);
删除表
SQL> DROP TABLE table_name;
查看当前数据库中的所有表
SHOW TABLES;
查看表的字段信息
DESC employee;
在上面员工表的基本上增加一个image列。
ALTER TABLE employee ADD image blob;
修改job列,使其长度为60。
ALTER TABLE employee MODIFY job varchar(60);
删除image列,一次只能删一列。
ALTER TABLE employee DROP image;
表名改为user。
RENAME TABLE employee TO user;
查看表格的创建细节
SHOW CREATE TABLE user;
修改表的字符集为gbk
ALTER TABLE user CHARACTER SET gbk;
列名name修改为username
ALTER TABLE user CHANGE name username varchar(100);
4.DML操作
4.1插入
语法:INSERT INTO 表名(列名1,列名2 ...)VALUES(列值1,列值2...);
注意:列名与列值的类型、个数、顺序要一一对应。
4.2修改
语法:UPDATE 表名 SET 列名1=列值1,列名2=列值2 ... WHERE 列名=值
4.3删除
语法: DELETE FROM 表名 WHERE 列名=值
TRUNCATE FROM 表名 WHERE 列名=值
DELETE 与 TRUNCATE区别:
- DELETE 删除表中的数据,表结构还在;删除后的数据可以找回
- TRUNCATE 删除是把表直接DROP掉,然后再创建一个同样的新表。
- 删除的数据不能找回。执行速度比DELETE快。
5.DQL数据查询
语法: SELECT 列名 FROM表名 【WHERE --> BROUP BY-->HAVING--> ORDER BY】
SELECT selection_list /要查询的列名称/
FROM table_list /要查询的表名称/
WHERE condition /行条件/
GROUP BY grouping_columns /对结果分组/
HAVING condition /分组后的行条件/
ORDER BY sorting_columns /对结果分组/
LIMIT offset_start, row_count /结果限定/
现有三个表 stu 、 dept 、 emp,如下所示



5.1简单查询
查询所有列
SELECT * FROM stu;
查询指定列
SELECT sid, sname, age FROM stu;
5.2条件查询
(1)查询性别为女,并且年龄小于50的记录
SELECT * FROM stu WHERE gender='female' AND age<50;
(2)查询学号为S_1001,或者姓名为liSi的记录
SELECT * FROM stu WHERE sid ='S_1001' ORsname='liSi';
(3)查询学号为S_1001,S_1002,S_1003的记录
SELECT * FROM stu
WHERE sid IN ('S_1001','S_1002','S_1003');
(4)查询学号不是S_1001,S_1002,S_1003的记录
SELECT * FROM tab_student
WHERE sid NOT IN('S1001','S1002','S_1003');
(5)查询年龄为null的记录
SELECT * FROM stu WHERE age IS NULL;
(6) 查询年龄在20到40之间的学生记录
SELECT *
FROM stu
WHERE age>=20 AND age<=40;
或者
SELECT *
FROM stu
WHERE age BETWEEN 20 AND 40;
(7) 查询性别非男的学生记录
SELECT *
FROM stu
WHERE gender!='male';
或者
SELECT *
FROM stu
WHERE gender<>'male';
或者
SELECT *
FROM stu
WHERE NOT gender='male';
(8) 查询姓名不为null的学生记录
SELECT *
FROM stu
WHERE NOT sname IS NULL;
或者
SELECT *
FROM stu
WHERE sname IS NOT NULL;
5.3 模糊查询
关键字: LIKE
通配符:_ 任意一个字母
%:任意0~n个字母
(1)查询姓名由5个字母构成的学生记录
SELECT *
FROM stu
WHERE sname LIKE '_';
模糊查询必须使用LIKE关键字。其中 “”匹配任意一个字母,5个“”表示5个任意字母。
(2)查询姓名由5个字母构成,并且第5个字母为“i”的学生记录
SELECT *
FROM stu
WHERE sname LIKE 'i';
(3)查询姓名以“z”开头的学生记录
SELECT *
FROM stu
WHERE sname LIKE 'z%';
其中“%”匹配0~n个任何字母。
(4)查询姓名中第2个字母为“i”的学生记录
SELECT *
FROM stu
WHERE sname LIKE '_i%';
(5)查询姓名中包含“a”字母的学生记录
SELECT *
FROM stu
WHERE sname LIKE '%a%';
5.4 字段控制查询
(1)去除重复记录
去除重复记录(两行或两行以上记录中系列的上的数据都相同),例如emp表中sal字段就存在相同的记录。当只查询emp表的sal字段时,那么会出现重复记录,那么想去除重复记录,需要使用DISTINCT:
SELECT DISTINCT sal FROM emp;
(2)查看雇员的月薪与佣金之和
因为sal和comm两列的类型都是数值类型,所以可以做加运算。如果sal或comm中有一个字段不是数值类型,那么会出错。
SELECT *,sal+comm FROM emp;
comm列有很多记录的值为NULL,因为任何东西与NULL相加结果还是NULL,所以结算结果可能会出现NULL。下面使用了把NULL转换成数值0的函数IFNULL:
SELECT *,sal+IFNULL(comm,0) FROMemp;
(3)给列名添加别名
在上面查询中出现列名为sal+IFNULL(comm,0),这很不美观,现在我们给这一列给出一个别名,为total:
SELECT *, sal+IFNULL(comm,0) AStotal FROM emp;
给列起别名时,是可以省略AS关键字的:
SELECT *,sal+IFNULL(comm,0) total FROM emp;
5.5 排序
(1) 查询所有学生记录,按年龄升序排序
SELECT *
FROM stu
ORDER BY sage ASC;
或者
SELECT *
FROM stu
ORDER BY sage;
(2) 查询所有学生记录,按年龄降序排序
SELECT *
FROM stu
ORDER BY age DESC;
(3) 查询所有雇员,按月薪降序排序,如果月薪相同时,按编号升序排序
SELECT * FROM emp
ORDER BY sal DESC,empno ASC;
5.6 聚合函数
聚合函数是用来做纵向运算的函数:
COUNT():统计指定列不为NULL的记录行数;
MAX():计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
MIN():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
SUM():计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
AVG():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;
IFNULL()
(1) COUNT
当需要纵向统计时可以使用COUNT()。
查询emp表中记录数:
SELECT COUNT(*) AS cnt FROM emp;
查询emp表中有佣金的人数:
SELECT COUNT(comm) cnt FROM emp;
注意,因为count()函数中给出的是comm列,那么只统计comm列非NULL的行数。
查询emp表中月薪大于2500的人数:
SELECT COUNT(*) FROM emp
WHERE sal > 2500;
统计月薪与佣金之和大于2500元的人数:
SELECT COUNT(*) AS cnt FROM empWHERE sal+IFNULL(comm,0) > 2500;
查询有佣金的人数,以及有领导的人数:
SELECT COUNT(comm), COUNT(mgr)FROM emp;
(2) SUM和AVG
当需要纵向求和时使用sum()函数。
查询所有雇员月薪和:
SELECT SUM(sal) FROM emp;
查询所有雇员月薪和,以及所有雇员佣金和:
SELECT SUM(sal), SUM(comm) FROMemp;
查询所有雇员月薪+佣金和:
SELECT SUM(sal+IFNULL(comm,0))FROM emp;
统计所有员工平均工资:
SELECT AVG(sal) FROM emp;
(3) MAX和MIN
查询最高工资和最低工资:
SELECT MAX(sal), MIN(sal) FROM emp;
求工资最高的人和钱,工资对低的人和钱:
select ename,sal from emp where sal = (select max(sal) from emp) or sal = (select min(sal) from emp);
select ename,sal from emp where sal =(select min(sal) from emp) union select ename,sal from emp where sal =(select max(sal) from emp);
5.7 分组查询
当需要分组查询时需要使用GROUP BY子句,例如查询每个部门的工资和,这说明要使用部分来分组。
注:凡和聚合函数同时出现的列名,则一定要写在group by 之后
5.7.1 分组查询
查询每个部门的部门编号和每个部门的工资和:
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;
5.7.2 HAVING子句
查询工资总和大于9000的部门编号以及工资和:
SELECT deptno, SUM(sal)
FROM emp
GROUP BY deptno
HAVING SUM(sal) > 9000;
注:having与where的区别:
1.having是在分组后对数据进行过滤,where是在分组前对数据进行过滤
2.having后面可以使用分组函数(统计函数)
where后面不可以使用分组函数。
WHERE是对分组前记录的条件,如果某行记录没有满足WHERE子句的条件,那么这行记录不会参加分组;而 HAVING是对分组后数据的约束。
5.8 LIMIT
LIMIT用来限定查询结果的起始行,以及总行数。
1查询5行记录,起始行从0开始
SELECT * FROM emp LIMIT 0, 5;
注意,起始行从0开始,即第一行开始!
2查询10行记录,起始行从3开始
SELECT* FROM emp LIMIT 3, 10;
5.8.3 分页查询
如果一页记录为10条,希望查看第3页记录应该怎么查呢?
第一页记录起始行为0,一共查询10行;
第二页记录起始行为10,一共查询10行;
第三页记录起始行为20,一共查询10行;
查询语句书写顺序:select – from- where- groupby- having- order by-limit
查询语句执行顺序:from - where -group by -having - select - order by-limit
6.多表查询
6.1 合并结果集
作用:合并结果集就是把两个select语句的查询结果合并到一起!
合并结果集有两种方式:
UNION:去除重复记录,例如:SELECT* FROM t1 UNION SELECT * FROM t2;
UNION ALL:不去除重复记录,例如:SELECT * FROM t1 UNION ALL SELECT * FROM t2。
注意:被合并的两个结果:列数、列类型必须相同。
select ename,phone from student union select name,phone_num from user;
6.2 连接查询
示例 1:现有两张表
emp表
CREATE TABLE emp(
empno INT,
ename VARCHAR(50),
job VARCHAR(50),
mgr INT,
hiredate DATE,
sal DECIMAL(7,2),
comm decimal(7,2),
deptno INT
);
#添加数据SQL语句省略
dept表
CREATE TABLE dept(
deptno INT,
dname varchar(14),
loc varchar(13)
);
#添加数据SQL语句省略
6.2.1 内连接
上面的连接语句就是内连接,但它不是SQL标准中的查询方式,可以理解为方言!
SQL标准的内连接为:
SELECT *
FROM emp e
INNER JOIN dept d
ON e.deptno=d.deptno;
内连接的特点:查询结果必须满足条件。
6.2.2 外连接
包括左外连接和右外连接,外连接的特点:查询出的结果存在不满足条件的可能。
a.左外连接
SELECT * FROM emp e
LEFT OUTER JOIN dept d
ON e.deptno=d.deptno;
左连接是先查询出左表(即以左表为主),然后查询右表,右表中满足条件的显示出来,不满足条件的显示NULL。
6.3 子查询
一个select语句中包含另一个完整的select语句。
子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个,或两个以上SELECT,那么就是子查询语句了。
子查询出现的位置:
a. where后,作为条为被查询的一条件的一部分;
b. from后,作表;
当子查询出现在where后作为条件时,还可以使用如下关键字:
a. any
b. all
子查询结果集的形式:
a. 单行单列(用于条件)
b. 单行多列(用于条件)
c. 多行单列(用于条件)
d. 多行多列(用于表)
示例:
1. 工资高于JONES的员工。
分析:
查询条件:工资>JONES工资,其中JONES工资需要一条子查询。
第一步:查询JONES的工资
SELECT sal FROM emp WHERE ename='JONES';
第二步:查询高于甘宁工资的员工
SELECT * FROM emp WHERE sal > (第一步结果);
结果:
SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename='JONES');
2. 查询与SCOTT同一个部门的员工。
子查询作为条件
子查询形式为单行单列
分析:
查询条件:部门=SCOTT的部门编号,其中SCOTT 的部门编号需要一条子查询。
第一步:查询SCOTT的部门编号
SELECT deptno FROM emp WHERE ename='SCOTT';
第二步:查询部门编号等于SCOTT的部门编号的员工
SELECT * FROM emp WHERE deptno = (SELECT deptno FROM emp WHERE ename='SCOTT');
3. 工资高于30号部门所有人的员工信息
分析:
SELECT * FROMemp WHERE sal>(SELECT MAX(sal)FROM emp WHERE deptno=30);
查询条件:工资高于30部门所有人工资,其中30部门所有人工资是子查询。高于所有需要使用all关键字。
第一步:查询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)
l 子查询作为条件
l 子查询形式为多行单列(当子查询结果集形式为多行单列时可以使用ALL或ANY关键字)

浙公网安备 33010602011771号