安装教程
导入现成的数据:进入到一个表内,然后source 路径
MySQL卸载- 双击安装包进行remove
cmd中 net start/stop mysql
MySQL常用命令TCL:事务控制语言(Transaction Control Language)commit rollback
DDL:数据定义语言 (Data Definition Language, DDL) create drop
DML:数据操纵语言(Data Manipulation Language, DML)insert delete
DQL:数据查询语言(Data Query Language, DQL)select
DCL(数据控制语言):grant授权,revoke撤销权限等。
查看数据库中的表: show databases; 创建表: create database 名字; 使用表: use 表的名字; 查看表:show tables; 查看数据库类型:desc 数据库名称: 查看版本号:select version(); 查看当前正在使用的数据库: select database();
DQL 数据查询语言 单表查询 检索数据 简单查询
select 字段名 from 表名
查询多个字段:逗号隔开
起别名:select deptno,dname as deptname from dept;
列参参与运算: select ename,sal*12 as yearSal from emp
空值检查: is null/is not null进行检查
因为null只表示空而不是一个特定的值,所以不能用=null
组会过滤:
and or 同时出现 and优先级更高
包含:in (相当于多个or,)/not in
通配符过滤:
LIKE %:任意字符
LIKE _:指代一个字符
SELECt DISTINCT job from emp;
可以去除重复项,distinct只可以在多字段的前方,但可以被包含在分组函数内,如:
SELECt count(DISTINCT job) from emp;
该语法返回工作的种类数
若有多个排序列 会按照第一个排序,若出现相同的值,再按第二个排序(这里就是先按工资排序,工资相同的按名字排)。
指定排序方向 DESC/ASC
limit 关键字(限制输出)查询薪资最少的前5个人
select ename,sal
-> from emp
-> order by sal
-> limit 5;
+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| JAMES | 950.00 |
| ADAMS | 1100.00 |
| WARD | 1250.00 |
| MARTIN | 1250.00 |
+--------+---------+
5 rows in set (0.00 sec)
完整用法:limit startIndex ,length
注意: startIndex 从0开始
通用分页:limit (pageNo-1)*pageSize,pageSize
| ifnull(数据,被当作的值) | 判断数据为空,则替换成,后边的值 |
|---|---|
| round | 四舍五入函数 |
数值处理
一个复杂的小李子:
返回首字母小写的名字和他们薪资在1500到3000之间的人选
mysql> select Concat(lower(subString(ename,1,1)),subString(ename,2,length(ename))), sal from emp where sal between 1500 and 3000; +----------------------------------------------------------------------+---------+ | Concat(lower(subString(ename,1,1)),subString(ename,2,length(ename))) | sal | +----------------------------------------------------------------------+---------+ | aLLEN | 1600.00 | | jonES | 2975.00 | | bLAKE | 2850.00 | | cLARK | 2450.00 | | sCOTT | 3000.00 | | tURNER | 1500.00 | | fORD | 3000.00 | +----------------------------------------------------------------------+---------+ 7 rows in set (0.00 sec)分组函数
分组函数自动忽略null
分组函数不能用在where后面,可以用在select后面,因为执行顺序,group by在where之后,where时还没有分组,但是select在分组之后,所以可以执行。
语法撰写顺序
- selectfromwheregroup by (having)order by
语法执行顺序fromwheregroup by (having)selectorder by
group by 可以包含任意数目的列
#查询每个部门每个工种薪资的最大值 mysql> select deptno,job,max(sal) from emp group by deptno,job; +--------+-----------+----------+ | deptno | job | max(sal) | +--------+-----------+----------+ | 20 | CLERK | 1100.00 | | 30 | SALESMAN | 1600.00 | | 20 | MANAGER | 2975.00 | | 30 | MANAGER | 2850.00 | | 10 | MANAGER | 2450.00 | | 20 | ANALYST | 3000.00 | | 10 | PRESIDENT | 5000.00 | | 30 | CLERK | 950.00 | | 10 | CLERK | 1300.00 | +--------+-----------+----------+ 9 rows in set (0.00 sec)
HAVINg 过滤分组
#平均薪资大于2000的部门
mysql> select deptno,avg(sal) from emp group by deptno
-> having avg(sal)>2000;
+--------+-------------+
| deptno | avg(sal) |
+--------+-------------+
| 20 | 2175.000000 |
| 10 | 2916.666667 |
+--------+-------------+
2 rows in set (0.00 sec)
此时where不能用,因为where针对行过滤,不针对分组过滤
但having和where优先使用where,因为where在数据分组之前就可以过滤,节省时间
单表查询的融合案例:
+-------+--------+-----------+------+------------+---------+---------+--------+ | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | +-------+--------+-----------+------+------------+---------+---------+--------+ | 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 | | 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 | | 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 | | 7566 | JonES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 | | 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 | | 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 | | 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 | | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 | | 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 | | 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 | | 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 | | 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 | | 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 | | 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 | +-------+--------+-----------+------+------------+---------+---------+--------+
找出每个岗位的平均薪资,要求显示平均薪资大于1500的,除MANAGER岗位以外的,并按照平均岗位薪资按降序排列
mysql> select job ,avg(sal) from emp where job<>'MANAGER' group by job having avg(sal)>1500 order by avg(sal) desc; +-----------+-------------+ | job | avg(sal) | +-----------+-------------+ | PRESIDENT | 5000.000000 | | ANALYST | 3000.000000 | +-----------+-------------+ 2 rows in set (0.00 sec)
多表查询 内部连接
等值连接
92语法: select e.ename,d.dname from emp e , deot d where e.deptno=d.deptno; 99语法: select e.ename,d.dname from emp e join deot d on e.deptno=d.deptno;
与92语法相比,连接的条件是独立的,如果后面还要筛选,后面可继续添加where
非等值连接
select e.ename,e.sal,e.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
自连接
同表连接
select a.ename,b.ename from emp a join emp b on a.mgr=b.empno;外部链接
select e.ename,d.dname from emp e left/right join deot d on e.deptno=d.deptno;
外部连接分左连接和右连接,会把左/右部分的所有属性都包含进来、
mysql> select e.ename,d.dname from emp e right join dept d on e.deptno=d.deptno; +--------+------------+ | ename | dname | +--------+------------+ ... | TURNER | SALES | | BLAKE | SALES | | MARTIN | SALES | | WARD | SALES | | ALLEN | SALES | | NULL | OPERATIONS | +--------+------------+ 15 rows in set (0.00 sec) mysql> select * from dept ; +--------+------------+----------+ | DEPTNO | DNAME | LOC | +--------+------------+----------+ | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | +--------+------------+----------+ 4 rows in set (0.01 sec)
因为dept里有一个40的部门,emp里没有。所以内连接只会有前14个语句,第15条数据是右外连接出的
多表联查select ... from a join b on a和b的连接条件 join c on a和c的连接条件子查询
where中的子查询
select ename,sal from emp where sal>(select min(sal) from emp);
from中的子查询
找出每个岗位的平均工资等级
select t.*,s.grade from (select job,avg(sal) as jsal from emp group by job ) t join salgrade s on t.jsal between s.losal and s.hisal; +-----------+-------------+-------+ | job | jsal | grade | +-----------+-------------+-------+ | CLERK | 1037.500000 | 1 | | SALESMAN | 1400.000000 | 2 | | MANAGER | 2758.333333 | 4 | | ANALYST | 3000.000000 | 4 | | PRESIDENT | 5000.000000 | 5 | +-----------+-------------+-------+ 5 rows in set (0.00 sec)组合查询 Union
合并时,要求列数要一致,Oracle还要求列的数据类型也要一致
select ename,job from emp where job=“MANAGER” union select ename,job from emp where job=“SALEMAN”
组合查询要比多数据查询要快
DDL 数据定义语言 创建表
create table tableName( columnName dataType(length), ……………….. columnName dataType(length) );
常见的数据类型:
drop table t_student;
DML 数据操纵语言 插入数据 insertinsert into t_student(student_id, student_name, birthday, email, classes_id) values (1002, 'zhangsan', '1988-01-01', 'qqq@163.com', 10); #也可以只加入一部分数据,其余数据会使用默认值 insert into t_student(student_id) values (1002); #如果是全值插入,可以省略字段名 insert into t_student values (1002, 'zhangsan', '1988-01-01', 'qqq@163.com', 10)
插入日期数据:
data:日期型,分为年月日
datatime: 长日期型,分为年月日时秒
#第一种:按顺序插入 insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values(9997,'zhangsan','MANAGER', null, '1981-06-12',3000, 500, 10); # 第二种: 使用now() 函数插入 insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values(9995,'zhangsan','MANAGER',null,now() ,3000, 500, 10);经典练习题
首先看一下练习数据库的内容:
show tables; +-------------------+ | Tables_in_sqltest | +-------------------+ | dept | | emp | | salgrade | +-------------------+ ---------------------------------------------------------------------------------- select * from dept; +--------+------------+----------+ | DEPTNO | DNAME | LOC | +--------+------------+----------+ | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | +--------+------------+----------+ select * from emp; +-------+--------+-----------+------+------------+---------+---------+--------+ | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | +-------+--------+-----------+------+------------+---------+---------+--------+ | 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 | | 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 | | 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 | | 7566 | JonES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 | | 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 | | 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 | | 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 | | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 | | 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 | | 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 | | 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 | | 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 | | 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 | | 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 | +-------+--------+-----------+------+------------+---------+---------+--------+ select * from salgrade; +-------+-------+-------+ | GRADE | LOSAL | HISAL | +-------+-------+-------+ | 1 | 700 | 1200 | | 2 | 1201 | 1400 | | 3 | 1401 | 2000 | | 4 | 2001 | 3000 | | 5 | 3001 | 9999 | +-------+-------+-------+ 5 rows in set (0.01 sec)
练习1:取得每个部门最高薪水的人员名称
每个部门最高薪水的人可能不止一个,因此不能直接用分组函数求得,那只会展示每个部门一个最高薪水,因此需要多表查询(子查询)。
在from里的子查询,先生成出每个部门的最大薪资,作为临时表,再查询出每个部门具有这个最大薪资的所有人
select e.ename,e.sal,e.deptno from emp e join (select deptno ,max(sal) as MAXSAL from emp group by deptno) t where e.deptno=t.deptno and e.sal=t.MAXSAL; +-------+---------+--------+ | ename | sal | deptno | +-------+---------+--------+ | BLAKE | 2850.00 | 30 | | SCOTT | 3000.00 | 20 | | KING | 5000.00 | 10 | | FORD | 3000.00 | 20 | +-------+---------+--------+ 4 rows in set (0.01 sec)
练习2:取得部门中(所有人的)平均的薪水等级
薪水和等级评定,需要连接emp和salgrade两张表。
首先获得每个人的薪水等级,然后按组划分进行平均求值。
select e.deptno,avg(s.grade) from emp e join salgrade s where e.sal between s.losal and s.hisal group by e.deptno; +--------+--------------+ | deptno | avg(s.grade) | +--------+--------------+ | 20 | 2.8000 | | 30 | 2.5000 | | 10 | 3.6667 | +--------+--------------+ 3 rows in set (0.00 sec)



