三天学习数据库——01
1、什么是表?
表:table是数据的组成单元,所有的数据都以表格的形式组织,目的是可读性强
一个表包括行和列:
行:被称为数据或记录(data)
列:被列为字段(column)
每一个字段应该包括哪些属性?
字段名、数据类型、相关约束
2、学习MySQL主要还是学习通用的SQL语句,SQL语句怎么分类?
DQL(数据查询语言):查询语句,凡是select语句都是DQL
DML(数据操作语言):insert delete update 对表中的数据进行增删改
DDL(数据定义语言):create drop alter 对表结构的增删改
TCL(事务控制语言):commit 提交事务,rollback 回滚事务
DCL(数据控制语言):grant 授权 revoke 撤销 权限等
3、导入数据
第一步:登陆MySQL数据库管理系统
dos命令窗口:
mysql -uroot -p***(password)
第二步:查看有哪些数据库属于MySQL命令
show databases;
第三步:创建属于我们自己的数据库
create database mydatabase;
第四步:使用mydatabase数据
use mydatabase;
第五步:查看当前使用的数据中有那些表?
show tables;
第六步:初始化数据
source sql脚本路径(SQL数据文件)
4、常用的SQL命令
创建数据库:create database mydatabase;
查询当前使用的数据库:select database();
查询数据库版本:select version();
终止一条正在编写的语句:\c
退出MySQL:exit;
5、什么是“SQL脚本”
当文件的扩展名是.sql,并且该文件中编写了大量的SQL语句,我们称之为sql脚本。
注意:可以直接使用source命令执行SQL脚本
当SQL脚本中的数据量太大的时候,无法打开,请使用source命令完成初始化
6、删除数据库
drop database mydatabase;
7、查看表结构
desc colname; (desc + 列名)
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| DEPTNO | int | NO | PRI | NULL | |
| DNAME | varchar(14) | YES | | NULL | |
| LOC | varchar(13) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
8、表中数据
select * from table;
+----------------------+
| Tables_in_mydatabase |
+----------------------+
| dept |
| emp |
| salgrade |
+----------------------+
9、查看创建表的语句
show create table emp;
| emp | CREATE TABLE `emp` (
`EMPNO` int NOT NULL,
`ENAME` varchar(10) DEFAULT NULL,
`JOB` varchar(9) DEFAULT NULL,
`MGR` int DEFAULT NULL,
`HIREDATE` date DEFAULT NULL,
`SAL` double(7,2) DEFAULT NULL,
`COMM` double(7,2) DEFAULT NULL,
`DEPTNO` int DEFAULT NULL,
PRIMARY KEY (`EMPNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
10、简单的查询语句(DQL)
语法格式:
select 字段名1,字段名2,字段3,… from 表名;
提示:
1、任何一条SQL语句以“;”结尾。
2、SQL语句不区分大小写。
查询员工的年薪?(字段可以参加数学运算)
select ename,sal*12 from emp;
+--------+----------+
| ename | sal*12 |
+--------+----------+
| SMITH | 9600.00 |
| ALLEN | 19200.00 |
| WARD | 15000.00 |
| JONES | 35700.00 |
| MARTIN | 15000.00 |
| BLAKE | 34200.00 |
| CLARK | 29400.00 |
| SCOTT | 36000.00 |
| KING | 60000.00 |
| TURNER | 18000.00 |
| ADAMS | 13200.00 |
| JAMES | 11400.00 |
| FORD | 36000.00 |
| MILLER | 15600.00 |
+--------+----------+
给查询结果的列重命名?
在想要更名的列后用as关键字
select ename,sal*12 as yearsal from emp;
+--------+----------+
| ename | yearsal |
+--------+----------+
| SMITH | 9600.00 |
| ALLEN | 19200.00 |
| WARD | 15000.00 |
| JONES | 35700.00 |
| MARTIN | 15000.00 |
| BLAKE | 34200.00 |
| CLARK | 29400.00 |
| SCOTT | 36000.00 |
| KING | 60000.00 |
| TURNER | 18000.00 |
| ADAMS | 13200.00 |
| JAMES | 11400.00 |
| FORD | 36000.00 |
| MILLER | 15600.00 |
+--------+----------+
或省略as关键字
select ename,sal*12 yearsal from emp;
别名中包括中文?
汉字用单引号括起来
select ename ‘姓名’, sal*12 ‘年薪’ from emp;
注意:标签SQL语句中字符串用单引号括起来,虽然MySQL支持双引号,尽量别用
查询所有字段?
select * from emp //实际开发中,不建议使用 * , 效率较低
11、条件查询
语法格式:
select
字段1,字段2,…
from
表名
where
条件;
执行顺序:先from,然后where,最后select
查询工资等于5000的员工姓名?
select ename ,sal from emp where sal = 5000;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
+-------+---------+
查询SMITH的工资?
select ename , sal from emp where ename = 'SMITH';
+-------+--------+
| ename | sal |
+-------+--------+
| SMITH | 800.00 |
+-------+--------+
找出工资高于3000的员工?
select ename,sal from emp where sal > 3000;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
+-------+---------+
找出工资不等于3000的员工
select ename,sal from emp where sal <> 3000;
select ename,sal from emp where sal != 3000;
+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| ALLEN | 1600.00 |
| WARD | 1250.00 |
| JONES | 2975.00 |
| MARTIN | 1250.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| KING | 5000.00 |
| TURNER | 1500.00 |
| ADAMS | 1100.00 |
| JAMES | 950.00 |
| MILLER | 1300.00 |
+--------+---------+
找出工资在1100与3000之间的员工(包括1100与3000)
select ename,sal from emp where sal >= 1100 and sal <= 3000;
select ename , sal from emp where sal between 1100 and 3000; //闭区间[1100,3000]
+--------+---------+
| ename | sal |
+--------+---------+
| ALLEN | 1600.00 |
| WARD | 1250.00 |
| JONES | 2975.00 |
| MARTIN | 1250.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| TURNER | 1500.00 |
| ADAMS | 1100.00 |
| FORD | 3000.00 |
| MILLER | 1300.00 |
+--------+---------+
select ename , sal from emp where sal between 3000 and 1100;
Empty set (0.00 sec)
between…and… 在使用的时候必须左小右大
between…and…除了可以用在数字上方面以外,还可以使用在字符串方面。
select ename from emp where ename between 'A' and 'C';
//在字符串方面,是左闭右开区间['A',‘C’)
+-------+
| ename |
+-------+
| ALLEN |
| BLAKE |
| ADAMS |
+-------+
找出哪些人津贴为NULL?
在数据库当中NULL不是一个值,代表什么也没有,为空。
空不是一个值,不能用等号来衡量,必须用 is null 或者 is not null ;
select ename from emp where comm is null;
+--------+
| ename |
+--------+
| SMITH |
| JONES |
| BLAKE |
| CLARK |
| SCOTT |
| KING |
| ADAMS |
| JAMES |
| FORD |
| MILLER |
+--------+
找出哪些人津贴不是空?
select ename from emp where comm is not null;
+--------+
| ename |
+--------+
| ALLEN |
| WARD |
| MARTIN |
| TURNER |
+--------+
找出哪些人没有津贴?
select ename , comm from emp where comm is null or comm = 0;
+--------+------+
| ename | comm |
+--------+------+
| SMITH | NULL |
| JONES | NULL |
| BLAKE | NULL |
| CLARK | NULL |
| SCOTT | NULL |
| KING | NULL |
| TURNER | 0.00 |
| ADAMS | NULL |
| JAMES | NULL |
| FORD | NULL |
| MILLER | NULL |
+--------+------+
找出工作岗位是MANAGE和SALESMAN的员工?
select ename , job from emp where job = 'MANAGER' or job = 'SALESMAN';
+--------+----------+
| ename | job |
+--------+----------+
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| JONES | MANAGER |
| MARTIN | SALESMAN |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| TURNER | SALESMAN |
+--------+----------+
and和or联合起来用:找出薪资大于2000的并且部门编号是20或30部门的员工
select ename,sal,deptno from emp where (deptno = 20 or deptno = 30) and sal > 2000;
+-------+---------+--------+
| ename | sal | deptno |
+-------+---------+--------+
| JONES | 2975.00 | 20 |
| BLAKE | 2850.00 | 30 |
| SCOTT | 3000.00 | 20 |
| FORD | 3000.00 | 20 |
+-------+---------+--------+
select ename,sal,deptno from emp where deptno = 20 or deptno = 30 and sal > 2000;
+-------+---------+--------+
| ename | sal | deptno |
+-------+---------+--------+
| SMITH | 800.00 | 20 |
| JONES | 2975.00 | 20 |
| BLAKE | 2850.00 | 30 |
| SCOTT | 3000.00 | 20 |
| ADAMS | 1100.00 | 20 |
| FORD | 3000.00 | 20 |
+-------+---------+--------+
注意:当运算符的优先级不确定的时候加小括号
in等同于or:找出工作岗位是MANAGER和SALESMAN的员工?
mysql> select ename ,job from emp where job in ('MANAGER','SALASMAN');
+-------+---------+
| ename | job |
+-------+---------+
| JONES | MANAGER |
| BLAKE | MANAGER |
| CLARK | MANAGER |
+-------+---------+
selece ename,job form emp where sal in (1000,5000);
//sal = 1000 or sal = 5000
//in后面的值不是区间,是具体的值
not in:不在这几个值当中的
模糊查询 like
找出名字当中含有O的?(在模糊查询中,必须掌握两个特殊的符号,一个是%,一个是_)
%代表任意多个字符,_代表任意1个字符
mysql> select ename from emp where ename like '%O%';
+-------+
| ename |
+-------+
| JONES |
| SCOTT |
| FORD |
+-------+
找出第二个字母是A的?
select ename from emp where ename like ‘_A%’;
找出名字中带有下划线的?
select ename from emp where ename like ‘%_%’;
12、排序 (升序、降序)
按照工资升序,找出员工名和薪资?
select ename,sal from emp order by sal;
+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| JAMES | 950.00 |
| ADAMS | 1100.00 |
| WARD | 1250.00 |
| MARTIN | 1250.00 |
| MILLER | 1300.00 |
| TURNER | 1500.00 |
| ALLEN | 1600.00 |
| CLARK | 2450.00 |
| BLAKE | 2850.00 |
| JONES | 2975.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| KING | 5000.00 |
+--------+---------+
注意:默认是升序,怎么指定升序或降序呢?asc表示升序,desc表示降序。
按照工资的降序排列,当工资相同时再按照名字的升序排序。
select ename,sal from emp order by sal desc,ename;
+--------+---------+
| ename | sal |
+--------+---------+
| KING | 5000.00 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| MARTIN | 1250.00 |
| WARD | 1250.00 |
| ADAMS | 1100.00 |
| JAMES | 950.00 |
| SMITH | 800.00 |
+--------+---------+
注意:越靠前的字段越能起到主导作用。只有当前面的 字段无法完成排序的时候,才会启用后面的字段。
找出工作 岗位是SALSMAN的员工,并且要求按照薪资的降序排列。
select ename,job,sal from emp where job = 'SALESMAN' order by sal desc;
+--------+----------+---------+
| ename | job | sal |
+--------+----------+---------+
| ALLEN | SALESMAN | 1600.00 |
| TURNER | SALESMAN | 1500.00 |
| WARD | SALESMAN | 1250.00 |
| MARTIN | SALESMAN | 1250.00 |
+--------+----------+---------+
select
* 第3步
from
tablename 第1步
where
条件 第2步
order by
… 第4步
13、分组函数
count 计数
sum 求和
avg 平均值
max 最大值
min 最小值
记住:所有分组函数都是对一组数据进行操作的
找出工资的总和
select sum(sal) from emp;
+----------+
| sum(sal) |
+----------+
| 29025.00 |
+----------+
找出最高的工资
select max(sal) from emp;
+----------+
| max(sal) |
+----------+
| 5000.00 |
+----------+
找出最低的工资
select min(sal) from emp;
+----------+
| min(sal) |
+----------+
| 800.00 |
+----------+
找出总人数
select count(*) from emp;
+----------+
| count(*) |
+----------+
| 14 |
+----------+
分组函数一共5个。
分组函数还有另一个名字:多行处理函数
多行处理函数的特点:输入多行,最终输出一行
分组处理函数自动忽略null。
select count(COMM) from emp;
+-------------+
| count(COMM) |
+-------------+
| 4 |
+-------------+
找出工资高于平均工资的员工
select e.sal from emp e where e.sal > (select avg(sal) from emp);
+---------+
| sal |
+---------+
| 2975.00 |
| 2850.00 |
| 2450.00 |
| 3000.00 |
| 5000.00 |
| 3000.00 |
+---------+
分组函数不能直接使用在where子句中
怎么解释:
因为group by 是在where执行之后才会执行,而count等分组函数是在group by执行之后
才能执行的,而在没有group by时,SQL也会提供一个缺省的group by,所以分组函数不能跟在where后面执行。
count(*)和count(具体某个字段),他们有什么区别?
count(*):表示统计总记录条数
count(comm):表示统计comm中不为null的数据总量。
单行处理函数:
什么是单行处理函数?
输入一行,输出一行。
计算每个员工的年薪?
select ename,(sal+comm)*12 from emp;
+--------+---------------+
| ename | (sal+comm)*12 |
+--------+---------------+
| SMITH | NULL |
| ALLEN | 22800.00 |
| WARD | 21000.00 |
| JONES | NULL |
| MARTIN | 31800.00 |
| BLAKE | NULL |
| CLARK | NULL |
| SCOTT | NULL |
| KING | NULL |
| TURNER | 18000.00 |
| ADAMS | NULL |
| JAMES | NULL |
| FORD | NULL |
| MILLER | NULL |
+--------+---------------+
结果出现错误!
重点:所有数据库都是这样规定的,只要有null参与的运算结果一定是null。
ifnull() 空处理函数
ifnull(可能为Null的数据,被当成什么处理):属于单行处理函数
select ename,(sal+ifnull(comm,0))*12 '年薪' from emp;
+--------+----------+
| ename | 年薪 |
+--------+----------+
| SMITH | 9600.00 |
| ALLEN | 22800.00 |
| WARD | 21000.00 |
| JONES | 35700.00 |
| MARTIN | 31800.00 |
| BLAKE | 34200.00 |
| CLARK | 29400.00 |
| SCOTT | 36000.00 |
| KING | 60000.00 |
| TURNER | 18000.00 |
| ADAMS | 13200.00 |
| JAMES | 11400.00 |
| FORD | 36000.00 |
| MILLER | 15600.00 |
+--------+----------+
15、group by 和 having
group by:按照某个字段或某些字段进行分组
having:是对分组之后的数据进行再次过滤
案例:找出每个工作岗位最高的工资
select ename, max(sal) from emp group by deptno;
+-------+----------+
| ename | max(sal) |
+-------+----------+
| SMITH | 3000.00 |
| ALLEN | 2850.00 |
| CLARK | 5000.00 |
+-------+----------+
注意:分组函数一般都会和group by联合使用,这也是为什么称他为分组函数的原因
并且任何一个分组函数(count、sum、avg、min、max)都在group by语句结束之后才 会执行的
当一条SQL语句没有group by的话,整张表会自成一组。
当一条语句中有group by的话,select后面的语句只能跟分组函数和参与分组的字段。
每一个岗位的平均薪资
select job, avg(sal) from emp group by job;
+-----------+-------------+
| job | avg(sal) |
+-----------+-------------+
| CLERK | 1037.500000 |
| SALESMAN | 1400.000000 |
| MANAGER | 2758.333333 |
| ANALYST | 3000.000000 |
| PRESIDENT | 5000.000000 |
+-----------+-------------+
多个字段能不能联合起来一起分组?
案例:找出每个部门不同工作岗位的最高薪资
select job, max(sal),deptno from emp group by job , deptno;
+-----------+----------+--------+
| job | max(sal) | deptno |
+-----------+----------+--------+
| CLERK | 1100.00 | 20 |
| SALESMAN | 1600.00 | 30 |
| MANAGER | 2975.00 | 20 |
| MANAGER | 2850.00 | 30 |
| MANAGER | 2450.00 | 10 |
| ANALYST | 3000.00 | 20 |
| PRESIDENT | 5000.00 | 10 |
| CLERK | 950.00 | 30 |
| CLERK | 1300.00 | 10 |
+-----------+----------+--------+
案例:找出每个部门的最高薪资 ,要求薪资大于2900的数据。
select max(sal) from emp where sal > 2900 group by deptno;
select max(sal),deptno from emp group by deptno having max(sal) > 2900; //这种方式效率低
+----------+
| max(sal) |
+----------+
| 3000.00 |
| 5000.00 |
+----------+
案例:找出每个部门的平均薪资,要求显示大于2000的。
select avg(sal),deptno from emp group by deptno having avg(sal) > 2000;
+-------------+--------+
| avg(sal) | deptno |
+-------------+--------+
| 2175.000000 | 20 |
| 2916.666667 | 10 |
+-------------+--------+
16、总结一个完整的DQL语句怎么写?
select
…
from
…
where
…
group by
…
having
…
order by
…