注意:原表数据不会被修改,只是查询结果去重。去重需要使用一个关键字:distinct(不同的)
mysql> select distinct job from emp;
+-----------+
| job |
+-----------+
| CLERK |
| SALESMAN |
| MANAGER |
| ANALYST |
| PRESIDENT |
| SALES |
+-----------+
6 rows in set (0.00 sec)
select ename, distinct job from emp;
这样编写是语法错误
使用distinct的时候只能放到所有字段的最前面。
如果distintc出现在job,deptno前面,表示两个字段联合起来去重。
统计一下工作岗位的数量
mysql> select count(distinct job) from emp ;
+---------------------+
| count(distinct job) |
+---------------------+
| 6 |
+---------------------+
1 row in set (0.00 sec)
emp表和dept表联合起来查询数据,从emp表中取员工姓名,从dept表中取部门名字。这种跨表查询就是连接查询。
根据语法的年代分类:
SQL92:1992年的时候出现的语法
SQL99: 1999年的时候出现的语法
我们是学习SQL99
表连接方式:内连接,外连接 ,全连接(用的少)
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接(左连接)
右外连接(右连接)
select ename,dname from emp,dept;
结果是数据乱套.也就是emp表中的记录数 * dept表中的记录数的数据;(笛卡尔积现象)
mysql> select ename,dname from emp,dept;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | ACCOUNTING |
| ALLEN | ACCOUNTING |
| WARD | ACCOUNTING |
| JONES | ACCOUNTING |
| MARTIN | ACCOUNTING |
...
案例:查询每个员工所在部门的名称?
案例:查询每个员工所在部门的名称?
连接时加条件,满足这个条件的记录被筛选出来。
#当员工表中的部门编号和部门表中的部门编号相等时查出的数据
mysql> select e.ename,e.deptno,d.dname from emp e,dept d where e.deptno = d.deptno;
+--------+--------+------------+
| ename | deptno | dname |
+--------+--------+------------+
| SMITH | 20 | RESEARCH |
| ALLEN | 30 | SALES |
| WARD | 30 | SALES |
| JONES | 20 | RESEARCH |
| MARTIN | 30 | SALES |
| BLAKE | 30 | SALES |
| CLARK | 10 | ACCOUNTING |
| SCOTT | 20 | RESEARCH |
| KING | 10 | ACCOUNTING |
| TURNER | 30 | SALES |
| ADAMS | 20 | RESEARCH |
| JAMES | 30 | SALES |
| FORD | 20 | RESEARCH |
| MILLER | 10 | ACCOUNTING |
| eric | 30 | SALES |
思考:最终查询的结果条数是15条记录,但是匹配的过程中,匹配的次数减少了吗?
没有减少,还是执行了两张表乘积的记录数,只不过是在部门表中选择了其中一个部门显示出数据。
表起别名,很重要。效率问题
可想而知:表连接的数越多,效率越慢。因为这个表的数目互相乘起来,遍历的次数一多,效率就变慢了。
案例:查询每一个员工所在的部门名称,显示员工名和部门名?
SQL92语法:mysql> select e.ename,e.deptno,d.dname from emp e,dept d where e.deptno = d.deptno ;
SQL99语法:mysql> select e.ename,e.deptno,d.dname from emp e join dept d on e.deptno = d.deptno;
逗号变join,where变成on就从SQL92语法变成了SQL99语法。(只是为了自己方便记忆而已啊!!!)
SQL92的语法缺点:如果表联查之后还要添加其他的过滤条件,需要再加and 后面加条件,我们称之为表结构不清晰。
SQL99的语法优点:表连接的条件是独立的,连接之后添加其他的过滤条件,再往后继续添加 where
SQL99结构:
select
…
from
a
inner join
b
on
a和b的连接条件
where
筛选条件
案例:找出每个员工的薪资等级,要求显示员工名,薪资,薪资等级?
mysql> select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
#条件不是一个等量关系,称为非等值连接。
+--------+---------+-------+
| ename | sal | grade |
+--------+---------+-------+
| SMITH | 800.00 | 1 |
| ALLEN | 3000.00 | 4 |
| WARD | 3000.00 | 4 |
| JONES | 3000.00 | 4 |
| MARTIN | 3000.00 | 4 |
| BLAKE | 3000.00 | 4 |
| CLARK | 3000.00 | 4 |
| SCOTT | 3000.00 | 4 |
| KING | 5000.00 | 5 |
| TURNER | 3000.00 | 4 |
| ADAMS | 1100.00 | 1 |
| JAMES | 950.00 | 1 |
| FORD | 3000.00 | 4 |
| MILLER | 1300.00 | 2 |
+--------+---------+-------+
14 rows in set (0.00 sec)
案例:查询员工的上级领导,要求显示员工名和对应的领导名?
技巧:一张表看成是两张表。
select ename,mgr from emp; 谁是领导
select ename,empno from emp; 谁是员工
a.mgr=b.empno(员工的领导编号 =领导的员工编号)
mysql> select a.ename '员工名', b.ename '领导名' from emp a join emp b on a.mgr=b.empno;
+--------+--------+
| 员工名 | 领导名 |
+--------+--------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
+--------+--------+
13 rows in set (0.00 sec)
内连接的特点:完成匹配这个条件的数据查询出来
右链接与内连接类似,唯一不同的是有主次分明(查询结果以join关键字右边的表为中心,将左表与右表相同数据查询出来)
捎带着查询左表查询时如果左表中没有与右边对应的数据则显示null,如果有数据则正常显示
右链接格式:select 字段... from 表名1 right join 表名2 on 连接条件... where 条件...
使用右链接查询emp
表中数据,显示员工姓名,部门名称。
添加:outer是可以省略的,加上可读性强一点。
mysql> select
-> e.ename,d.dname
-> from
-> emp e
-> right outer join
-> dept d
-> on
-> e.deptno =d.deptno;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
| eric | SALES |
| NULL | OPERATIONS |
| NULL | 研发部123 |
| NULL | 人力部门 |
| NULL | XiaoShouBu |
| NULL | YanFaBu |
| NULL | JiShuBu |
| NULL | MeiTiBu |
| NULL | 创新部 |
| NULL | 研发部123 |
| NULL | 设计部 |
+--------+------------+
25 rows in set (0.00 sec)
左连接与内连接类似,与右链接相反,查询时以左表为中心查询
查询是以左表为中心查询,如果没有数据则显示null,如果有数据则正常显示
左连接格式:select 字段... from 表名1 left join 表名2 on 连接条件... where 条件...
使用左链接查询emp
表中数据,显示员工部门,员工姓名。
案例:使用左链接查询emp
表中数据,显示员工姓名,部门名称想要显示出与右连接相同的效果
mysql> select e.ename,d.dname from dept d left outer join emp e on d.deptno =e.deptno;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
| eric | SALES |
| NULL | OPERATIONS |
| NULL | 研发部123 |
| NULL | 人力部门 |
| NULL | XiaoShouBu |
| NULL | YanFaBu |
| NULL | JiShuBu |
| NULL | MeiTiBu |
| NULL | 创新部 |
| NULL | 研发部123 |
| NULL | 设计部 |
+--------+------------+
左连接:mysql> select e.ename,d.dname from emp e right join dept d on d.deptno =e.deptno;
右连接:mysql> select e.ename,d.dname from dept d left join emp e on d.deptno =e.deptno;
可以很直观的看出right join是以join关键字右边为主表,左表是捎带的表。left join是以join关键字左边为主表右表是捎带的表。
添加:outer是可以省略的,加上可读性强一点。
正确。
案例:查询每一个员工的上级领导,要求显示所有的员工名字和领导名?
mysql> select e.ename '员工' ,m.ename '领导' from emp e left join emp m on e.mgr = m.empno;
+--------+-------+
| 员工 | 领导 |
+--------+-------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| KING | NULL |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
| eric | NULL |
+--------+-------+
15 rows in set (0.00 sec)
可以看出外连接中员工king对应的是领导null。
语法:
select
…
from
a
join
b
on
a和b的连接条件
join
c
on
a和c的连接条件
join
d
on
a和d的连接条件
一条SQL中的内连接和外连接可以混合。都可以实现!
案例:找出每一个员工的部门名称以及工资等级,要求显示员工名,部门名,薪资,薪资等级?
mysql> select e.ename,d.dname,e.sal,s.grade from emp e join dept d on e.deptno =d.deptno join salgrade s on e.sal between s.losal
-> and s.hisal ;
+--------+------------+---------+-------+
| ename | dname | sal | grade |
+--------+------------+---------+-------+
| SMITH | RESEARCH | 800.00 | 1 |
| ALLEN | SALES | 3000.00 | 4 |
| WARD | SALES | 3000.00 | 4 |
| JONES | RESEARCH | 3000.00 | 4 |
| MARTIN | SALES | 3000.00 | 4 |
| BLAKE | SALES | 3000.00 | 4 |
| CLARK | ACCOUNTING | 3000.00 | 4 |
| SCOTT | RESEARCH | 3000.00 | 4 |
| KING | ACCOUNTING | 5000.00 | 5 |
| TURNER | SALES | 3000.00 | 4 |
| ADAMS | RESEARCH | 1100.00 | 1 |
| JAMES | SALES | 950.00 | 1 |
| FORD | RESEARCH | 3000.00 | 4 |
| MILLER | ACCOUNTING | 1300.00 | 2 |
+--------+------------+---------+-------+
14 rows in set (0.00 sec)
升级案例: 案例:找出每一个员工的部门名称以及工资等级,还有上级领导。要求显示员工名,部门名,领导名,薪资,薪资等级?
mysql> select e.ename ‘员工’,d.dname ‘部门’,e.sal ‘薪资’, m.ename ‘领导’,s.grade ‘薪资等级’ from emp e join dept d on e.deptno =d.deptno join salgrade s on e.sal between s.losal and s.hisal left join emp m on e.mgr =m.empno;
mysql> select e.ename '员工',d.dname '部门',e.sal '薪资', m.ename '领导',s.grade '薪资等级' from emp e join dept d on e.deptno =d.deptno join salgrade s on e.sal between s.losal and s.hisal left join emp m on e.mgr =m.empno;
+--------+------------+---------+-------+----------+
| 员工 | 部门 | 薪资 | 领导 | 薪资等级 |
+--------+------------+---------+-------+----------+
| SMITH | RESEARCH | 800.00 | FORD | 1 |
| ALLEN | SALES | 3000.00 | BLAKE | 4 |
| WARD | SALES | 3000.00 | BLAKE | 4 |
| JONES | RESEARCH | 3000.00 | KING | 4 |
| MARTIN | SALES | 3000.00 | BLAKE | 4 |
| BLAKE | SALES | 3000.00 | KING | 4 |
| CLARK | ACCOUNTING | 3000.00 | KING | 4 |
| SCOTT | RESEARCH | 3000.00 | JONES | 4 |
| KING | ACCOUNTING | 5000.00 | NULL | 5 |
| TURNER | SALES | 3000.00 | BLAKE | 4 |
| ADAMS | RESEARCH | 1100.00 | SCOTT | 1 |
| JAMES | SALES | 950.00 | BLAKE | 1 |
| FORD | RESEARCH | 3000.00 | JONES | 4 |
| MILLER | ACCOUNTING | 1300.00 | CLARK | 2 |
+--------+------------+---------+-------+----------+
注意:如果没有左连接的时候,数据就不对了,也只有这样king才能出来
select语句中嵌套select语句,被嵌套的select语句称为子查询。
select
(select)
from
(select)
where
(select)
案例: 找出比最低工资高的员工的姓名和工资?
select min(sal) from emp
实现思路:第一步先查出最低工资
第二步 查出比最低工资高的
select ename, sal from emp where sal >800;
第三步 合并两个sql语句
select ename, sal from emp where sal > (select min(sal) from emp);
注意:from后面的子查询,可以将子查询的结果当作一张临时表。(技巧)
案例:找出每一个岗位的平均工资的薪资等级
第一步: 找出每个岗位的平均工资(按照岗位分组求平均值)
mysql> select job, avg(sal) from emp group by job
-> ;
+-----------+-------------+
| job | avg(sal) |
+-----------+-------------+
| CLERK | 1037.500000 |
| SALESMAN | 3000.000000 |
| MANAGER | 3000.000000 |
| ANALYST | 3000.000000 |
| PRESIDENT | 5000.000000 |
| SALES | NULL |
+-----------+-------------+
6 rows in set (0.00 sec
# 把此表作为e表
第二步:把上面的结果当作一张真实表去查,然后将这个表中的平均工资与salagrade表进行比对,找出对应的薪资等级
mysql> select grade,losal,hisal 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.00 sec)
#把此表作为s表
把两张表连接起来,条件:e表中 avg(sal) between s.losal and s.hisal;
可能咱们首先带来的想法是这样的:
select grade from salgrade where (select avg(sal) from emp group by job) between losal and hisal;
ERROR 1242 (21000): Subquery returns more than 1 row
不好意思,显示查的行数是多行报错,这是不正确的。
怎末办?
使用别名和表连接来搞
mysql> select e.job,e.avg(sal),s.grade from salgrade s join (select job, avg(sal) from emp group by job) e on
-> e.avg(sal) between losal and hisal;
ERROR 1630 (42000): FUNCTION e.avg does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual
不好意思啦,显示e.avg(sal)这个函数不存在,mysql自动把这个语句当做函数来执行,所以报错。
怎么办?把里面的字段名起一个别名
mysql> select e.job,e.avgsal,s.grade from salgrade s join (select job,avg(sal) as avgsal from emp group by job) e
-> on e.avgsal between s.losal and s.hisal;
+-----------+-------------+-------+
| job | avgsal | grade |
+-----------+-------------+-------+
| CLERK | 1037.500000 | 1 |
| SALESMAN | 3000.000000 | 4 |
| MANAGER | 3000.000000 | 4 |
| ANALYST | 3000.000000 | 4 |
| PRESIDENT | 5000.000000 | 5 |
+-----------+-------------+-------+
5 rows in set (0.00 sec)
案例:找出每一个员工的部门名称,要求显示员工名,部门名?
1、 查出员工名
mysql> select ename,deptno from emp;
+--------+--------+
| ename | deptno |
+--------+--------+
| SMITH | 20 |
| ALLEN | 30 |
| WARD | 30 |
| JONES | 20 |
| MARTIN | 30 |
| BLAKE | 30 |
| CLARK | 10 |
| SCOTT | 20 |
| KING | 10 |
| TURNER | 30 |
| ADAMS | 20 |
| JAMES | 30 |
| FORD | 20 |
| MILLER | 10 |
| eric | 30 |
+--------+--------+
15 rows in set (0.00 sec)
2、查出部门名
mysql> select dname,deptno from dept;
+------------+--------+
| dname | deptno |
+------------+--------+
| ACCOUNTING | 10 |
| RESEARCH | 20 |
| SALES | 30 |
| OPERATIONS | 40 |
| 研发部123 | 41 |
| 人力部门 | 42 |
| XiaoShouBu | 43 |
| YanFaBu | 44 |
| JiShuBu | 45 |
| MeiTiBu | 46 |
| 创新部 | 47 |
| 研发部123 | 49 |
| 设计部 | 53 |
+------------+--------+
13 rows in set (0.00 sec)
3、两个表中的的deptno是对应,用此字段连接两表
方案一:
mysql> select e.ename,d.dname from emp e join dept d where e.deptno=d.deptno;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
| eric | SALES |
+--------+------------+
15 rows in set (0.00 sec)
方案二:
select e.ename, ( select d.dname from dept d where d.deptno = e.deptno) dname from emp e;
#这种写法的缺陷:嵌套的子查询语句只能是查询一个字段,也就是只能返回一个结果,多余一条就报错
案例:查询工作岗位是MANAGER和SALESMAN的员工?
第一步:查询工作岗位是manager的是员工
mysql> select ename,job from emp where job='manager' ;
+-------+---------+
| ename | job |
+-------+---------+
| JONES | MANAGER |
| BLAKE | MANAGER |
| CLARK | MANAGER |
+-------+---------+
3 rows in set (0.00 sec)
第二步:查询工作岗位是salesman的员工
mysql> select ename,job from emp where job='salesman';
+--------+----------+
| ename | job |
+--------+----------+
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| MARTIN | SALESMAN |
| TURNER | SALESMAN |
+--------+----------+
第三步:
实现方法一:使用or关键字得出结果
mysql> 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 |
+--------+----------+
7 rows in set (0.00 sec)
实现方法二:使用in关键字得出结果
mysql> select ename,job from emp where job in ( 'manager' ,'salesman');
+--------+----------+
| ename | job |
+--------+----------+
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| JONES | MANAGER |
| MARTIN | SALESMAN |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| TURNER | SALESMAN |
+--------+----------+
实现方法三:使用union关键字
mysql> select ename,job from emp where job='manager' union select ename,job from emp where job='salesman';
+--------+----------+
| ename | job |
+--------+----------+
| JONES | MANAGER |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| MARTIN | SALESMAN |
| TURNER | SALESMAN |
+--------+----------+
7 rows in set (0.00 sec)
案例:查询工作岗位是MANAGER和SALESMAN的员工?这个案例使用or,in,union都可以实现需求,那么使用union的效率会高一点?为啥?
对于表连接来说 ,每增加一个表,都会增加笛卡尔集,但是使用union可以减少匹配的次数。在减少匹配次数的情况下还能完成需求。
例如:
表a ,表b,表c
a 连接 b 连接 c
a:10条记录
b:10条记录
c: 10条记录
匹配次数是1000次
使用union的话
a连接b 一个结果:10 * 10 =100
a连接c 一个结果: 10 * 10 =100
匹配的此时是100+100 =200
两相对比,union好。
忘记了看2.3同志。
1 union在进行结果集的合并的时候,要求两个结果的列数是相同的(在这里因为少了一列,job,)
mysql> select ename,job from emp where job='manager' union select ename from emp where job='salesman';
ERROR 1222 (21000): The used SELECT statements have a different number of columns
2 union在进行结果集的合并的时候,两个字段的类型可以是不一致的(在oracle中报错:要求结果和结果的列的类型是一致的)
mysql> select ename,job from emp where job='manager' union select ename, sal from emp where job='salesman';
+--------+---------+
| ename | job |
+--------+---------+
| JONES | MANAGER |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| ALLEN | 3000.00 |
| WARD | 3000.00 |
| MARTIN | 3000.00 |
| TURNER | 3000.00 |
+--------+---------+
7 rows in set (0.00 sec)
百度默认:一页显示10条件记录
分页的作用是为了提升用户的体验。可以一页一页的显示
limit怎么用?
limit 的完整用法:limit startIndex, length
startIndex:起始下标,默认是0,
length:长度
只写一个表示取的是前5: limit 5;
取前5条记录。
mysql> select ename ,sal from emp order by sal desc limit 0,5;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
| ALLEN | 3000.00 |
| WARD | 3000.00 |
| JONES | 3000.00 |
| BLAKE | 3000.00 |
+-------+---------+
5 rows in set (0.00 sec)
如果报错:
mysql> select ename ,sal from emp order by sal desc limit 0,5;
ERROR 1327 (42000): Undeclared variable: 0,5
#是因为 0,空格 5 也就是0和5之间多了空格。去掉空格就好。
mysql> select ename,sal from emp order by sal desc limit 2,3;
+-------+---------+
| ename | sal |
+-------+---------+
| WARD | 3000.00 |
| JONES | 3000.00 |
| BLAKE | 3000.00 |
+-------+---------+
3 rows in set (0.00 sec)
每页显示3条记录
第一页 0 3 [0 1 2]
第二页 3 3 [3 4 5]
第三页 6 3 [6 7 8]
每页显示pageSize条记录
第pageNo页: limit (pageNo-1)* pageSize,pageSize
此时发现 开始的索引(下标)是(pageNo-1)* pageSize(每页显示记录数)
public static void main(String[] args){
//用户提交过来一个页码,以及每页显示的记录条数
int pageNo = 5; //当前页码
int pageSize = 3 ;//每页显示的记录数
int startIndex = (pageNo-1) * pageSize;
String sql = “select …limit” + startIndex +“,” +pageSize;
}
select
…
from
…
where
…
group by
…
having
…
order by
…
limit
…
建表属于DDL语句,(DDL包括: create drop alter)
create table 表名(字段名1,数据类型,字段名2,数据类型2,字段名3,数据类型);
表明:建议以t_或者tbl__开始,可读性强。
字段名:见名知意
表名和字段名都属于标识符
varchar,char,int,bigint,float,double,date,datetime,clob,blob
:可变长度的字符串。它能够根据传过来的实际长度,动态的分配空间。
优点:节省空间
缺点:需要动态的分配空间,速度慢
:定长字符串。不管实际的数据长度是多少。分配固定的长度的空间去存储数据。使用不恰当的时候,可能会导致空间的浪费。
优点:不需要动态的分配空间,速度快
缺点:使用不当可能会导致空间的浪费
性别字段你选什么?char 固定
姓名字段你选什么? varchar 不固定
数字中的整形,等同与Java中的int
数字中的长整型。等同与Java中的long
单精度的浮点类型
双精度的浮点类型
短日期类型
长日期类型
字符大对象最多可以存储4G的字符串
比如:存储一个文章,存储一个说明。
超过255个字符的都要采用clob字符大对象来存储
Character Large Object:字符大对象clob
二进制大对象
专门用来存储视频,图片,声音等流媒体数据
往BLOB类型的字段上插入数据的时候,例如插入一个图片,视频等。
需要使用IO流才可以。
t_movie 电影表 (专门存储电影信息)
编号 | 名字 | 描述信息 | 上映日期 | 时长 | 海报 | 类型 |
---|---|---|---|---|---|---|
no(bigint) | name(varchar) | description(clob) | playtime(date) | time(double) | image(blob) | type(char) |
1000 | 西游 | 。。。。。 | 2022-10-22 | 1.5 | .。。。。 | ‘1’ |
1002 | 白发魔女 | 。。。。。 | 2022-10-22 | 1.5 | .。。。。 | ‘2’ |
create table t_student (no int(3),name varchar(255) , age int(3),sex char(1), email varchar(255) );
#如果这张表不存报错
drop table t_student
#第二种删除 这张表没有的话是不会报错的
drop table if exists t_student;
insert into t_student(name,age,sex,email) values('eric',12,'m','123@qq.com');
注意:添加的数值要和字段名的类型是对应的,添加的顺序可以随便,可多可少。
没有给其他的值赋值时候,默然是null.
也可以在建表的时候,给这张表一个默认值。
create table t_police (no int(3),name varchar(255) , age int(3),sex char(1) default 'm', email varchar(255) );
mysql> insert into t_police (no, name) values (1,'eric');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_police;
+------+------+------+------+-------+
| no | name | age | sex | email |
+------+------+------+------+-------+
| 1 | eric | NULL | m | NULL |
+------+------+------+------+-------+
1 row in set (0.00 sec)
这时侯,这张表默认的sex是m。
数字格式化:format
mysql> select ename,empno, format(sal,'$999,999') from emp;
+--------+-------+------------------------+
| ename | empno | format(sal,'$999,999') |
+--------+-------+------------------------+
| SMITH | 7369 | 800 |
| ALLEN | 7499 | 3,000 |
| WARD | 7521 | 3,000 |
| JONES | 7566 | 3,000 |
| MARTIN | 7654 | 3,000 |
| BLAKE | 7698 | 3,000 |
| CLARK | 7782 | 3,000 |
| SCOTT | 7788 | 3,000 |
| KING | 7839 | 5,000 |
| TURNER | 7844 | 3,000 |
| ADAMS | 7876 | 1,100 |
| JAMES | 7900 | 950 |
| FORD | 7902 | 3,000 |
| MILLER | 7934 | 1,300 |
| eric | 7938 | NULL |
+--------+-------+------------------------+
15 rows in set, 15 warnings (0.00 sec)
str_to_date :将字符串转化成日期
mysql> select str_to_date ('22,10,2022 ','%d,%m,%Y');
+----------------------------------------+
| str_to_date ('22,10,2022 ','%d,%m,%Y') |
+----------------------------------------+
| 2022-10-22 |
+----------------------------------------+
1 row in set (0.00 sec)
date_format:将日期转化成字符串
mysql> select date_format('2022-10-22 21:02:59' ,'%Y -%m-%d %H:%I:%S');
+----------------------------------------------------------+
| date_format('2022-10-22 21:02:59' ,'%Y -%m-%d %H:%I:%S') |
+----------------------------------------------------------+
| 2022 -10-22 21:09:59 |
+----------------------------------------------------------+
1 row in set (0.00 sec)
注意:数据库中有一条命名规范;
所有的标识符都是全部小写,单词和单词之间使用下划线连接。
创建一个生日表
create table t_birthday(id int(3),name varchar(255), birth date);
插入数据
mysql> insert into t_birthday(id ,name,birth) values(1,'zebra','22-10-2022');
ERROR 1292 (22007): Incorrect date value: '22-10-2022' for column 'birth' at row 1
#报错:日期值不对
使用str_to_date
mysql> insert into t_birthday(id ,name,birth) values(1,'zebra',str_to_date('22-10-2022','%d-%m-%Y'));
Query OK, 1 row affected (0.00 sec)
str_to_date 函数是将字符串转换为date类型,通常使用在插入date的语句之中。
好的信息是如果插入的语句是%Y-%m-%d的这种类型,那么str_to_date这种函数就可以不使用了,mysql会自动把此字符串转换成date类型的
mysql> insert into t_birthday(id ,name,birth) values(1,'zebra','2023-10-22'); Query OK, 1 row affected (0.01 sec)
查询的时候可以用特定的日期格式显示吗?
使用date_format函数通常使用在查询的使用场景之中
格式:date_format(字段名,‘我们想要展现出来的字符串类型’)
mysql> select id,name, date_format(birth,'%Y-%m-%d') from t_birthday;
+------+-------+-------------------------------+
| id | name | date_format(birth,'%Y-%m-%d') |
+------+-------+-------------------------------+
| 1 | zebra | 2022-10-22 |
| 1 | zebra | 2023-10-22 |
+------+-------+-------------------------------+
2 rows in set (0.00 sec)
而MySQL中查询之后日期默认的字符串类型是’%Y-%m-%d’
mysql> select * from t_birthday;
+------+-------+------------+
| id | name | birth |
+------+-------+------------+
| 1 | zebra | 2022-10-22 |
| 1 | zebra | 2023-10-22 |
+------+-------+------------+
2 rows in set (0.00 sec)
Java中的日期格式:yyyy-MM-dd HH-mm-ss SSS (小大 小大 小小大)
date是短日期 只包括了年月日信息
datetime是长日期包括了年月日时分秒信息
mysql> create table t_birthday(id int(3), birth date,create_time datetime);
Query OK, 0 rows affected, 1 warning (0.02 sec)
mysql> desc t_birthday
-> ;
+-------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+-------+
| id | int(3) | YES | | NULL | |
| birth | date | YES | | NULL | |
| create_time | datetime | YES | | NULL | |
+-------------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql 中短日期的默认类型是 %Y-%m-%d
mysql 中长日期的默认类型是 %Y-%m-%d %h:%i:%s
mysql> insert into t_birthday(id,birth,create_time) values(1,'2022-10-22','2022-10-22 21:44:59');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_birthday;
+------+------------+---------------------+
| id | birth | create_time |
+------+------------+---------------------+
| 1 | 2022-10-22 | 2022-10-22 21:44:59 |
+------+------------+---------------------+
1 row in set (0.00 sec)
在MySQL当中怎么获取当前系统的时间?
使用now()函数获取当前系统的时间,并且获取到的时间是带有时分秒信息,是datetime类型的!!!
mysql> insert into t_birthday(id,birth,create_time) values(1,'2022-10-22',now());
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_birthday;
+------+------------+---------------------+
| id | birth | create_time |
+------+------------+---------------------+
| 1 | 2022-10-22 | 2022-10-22 21:44:59 |
| 1 | 2022-10-22 | 2022-10-22 21:49:26 |
+------+------------+---------------------+
2 rows in set (0.00 sec)
语法格式:update 表名 set 字段1 = 值1,字段2 = 值2 …where 条件;
注意:如果没有条件限制,会导致表中的所有数据全部更新。
mysql> select * from t_birthday;
+------+------------+---------------------+
| id | birth | create_time |
+------+------------+---------------------+
| 2 | 2022-10-22 | 2022-10-22 21:59:10 |
| 1 | 2022-10-22 | 2022-10-22 21:59:20 |
+------+------------+---------------------+
2 rows in set (0.00 sec)
mysql> update t_birthday set id=3, birth='1998-06-18', create_time='1998-06-18 08:00:00' where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from t_birthday;
+------+------------+---------------------+
| id | birth | create_time |
+------+------------+---------------------+
| 3 | 1998-06-18 | 1998-06-18 08:00:00 |
| 1 | 2022-10-22 | 2022-10-22 21:59:20 |
+------+------------+---------------------+
2 rows in set (0.00 sec)
语法格式:delete from 表名 where 条件;
注意:如果没有条件限制,会导致表中的所有数据全部删除。
mysql> delete from t_birthday where id=3;
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_birthday;
+------+------------+---------------------+
| id | birth | create_time |
+------+------------+---------------------+
| 1 | 2022-10-22 | 2022-10-22 21:59:20 |
+------+------------+---------------------+
1 row in set (0.00 sec)