mysql day02学习笔记-杜老师(动力节点)

mysql day02学习笔记-杜老师(动力节点)

1.distinct:把查询结果去除重复记录

注意:原表数据不会被修改,只是查询结果去重。去重需要使用一个关键字: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)

2.连接查询

2.1. 什么是连接查询?

emp表和dept表联合起来查询数据,从emp表中取员工姓名,从dept表中取部门名字。这种跨表查询就是连接查询。

2.2.连接查询的分类?

根据语法的年代分类:
SQL92:1992年的时候出现的语法
SQL99: 1999年的时候出现的语法
我们是学习SQL99

表连接方式:内连接,外连接 ,全连接(用的少)
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接(左连接)
右外连接(右连接)

2.3.当两张表进行连接查询的时候,没有任何的条件限制会发生什么现象?

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 |
...

案例:查询每个员工所在部门的名称?

2.4.如何避免笛卡尔积现象哪?

案例:查询每个员工所在部门的名称?
连接时加条件,满足这个条件的记录被筛选出来。

#当员工表中的部门编号和部门表中的部门编号相等时查出的数据
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条记录,但是匹配的过程中,匹配的次数减少了吗?
没有减少,还是执行了两张表乘积的记录数,只不过是在部门表中选择了其中一个部门显示出数据。
表起别名,很重要。效率问题
可想而知:表连接的数越多,效率越慢。因为这个表的数目互相乘起来,遍历的次数一多,效率就变慢了。

2.5.内连接之等值连接

案例:查询每一个员工所在的部门名称,显示员工名和部门名?
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
筛选条件

2.6.内连接之非等值连接

案例:找出每个员工的薪资等级,要求显示员工名,薪资,薪资等级?

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)

2.7.内连接之自连接

案例:查询员工的上级领导,要求显示员工名和对应的领导名?
技巧:一张表看成是两张表。
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)

内连接的特点:完成匹配这个条件的数据查询出来

2.8.右外连接

右链接与内连接类似,唯一不同的是有主次分明(查询结果以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)

2.9.左外连接

左连接与内连接类似,与右链接相反,查询时以左表为中心查询
查询是以左表为中心查询,如果没有数据则显示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   | 设计部     |
+--------+------------+

2.10. 左(外)连接与右(外)连接的区别

左连接: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是可以省略的,加上可读性强一点。

2.11.外连接的查询结果条数一定是 >=内连接的查询结果条数?

正确。
案例:查询每一个员工的上级领导,要求显示所有的员工名字和领导名?

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。

2.12.三张表,四张表怎么连接?

语法:
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才能出来

3. 子查询?

3.1. 什么是子查询?

select语句中嵌套select语句,被嵌套的select语句称为子查询。

3.2. 子查询

select
(select)
from
(select)
where
(select)

3.3. where子句中的子查询

案例: 找出比最低工资高的员工的姓名和工资?
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); 

3.4.from后面的子查询

注意: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)

3.5. select后面出现的子查询

案例:找出每一个员工的部门名称,要求显示员工名,部门名?
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;
#这种写法的缺陷:嵌套的子查询语句只能是查询一个字段,也就是只能返回一个结果,多余一条就报错

4.union合并查询结果集

案例:查询工作岗位是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同志。

4.1 union在使用的时候有什么注意事项?

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)

5.limit

5.1 limit是将查询结果的一部分取出来,通常使用在分页查询之中。

百度默认:一页显示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之间多了空格。去掉空格就好。 

5.2 注意的是mysql当中limit是在order by之后执行的

5.3 取出工资排名在[3, 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)

5.4 分页

每页显示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;
}

6. DQL语法总结

select

from

where

group by

having

order by

limit

7.表的创建(建表)

7.1 建表的语句

建表属于DDL语句,(DDL包括: create drop alter)
create table 表名(字段名1,数据类型,字段名2,数据类型2,字段名3,数据类型);
表明:建议以t_或者tbl__开始,可读性强。
字段名:见名知意
表名和字段名都属于标识符

7.2 关于mysql中的数据类型

varchar,char,int,bigint,float,double,date,datetime,clob,blob

7.2.1.varchar(最长255)

:可变长度的字符串。它能够根据传过来的实际长度,动态的分配空间。
优点:节省空间
缺点:需要动态的分配空间,速度慢

7.2.2.char(最长255)

:定长字符串。不管实际的数据长度是多少。分配固定的长度的空间去存储数据。使用不恰当的时候,可能会导致空间的浪费。
优点:不需要动态的分配空间,速度快
缺点:使用不当可能会导致空间的浪费

7.2.3.varchar 和char我们应该怎么选择?

性别字段你选什么?char 固定
姓名字段你选什么? varchar 不固定

7.2.4.int(最长11)

数字中的整形,等同与Java中的int

7.2.5.bigint

数字中的长整型。等同与Java中的long

7.2.6.float

单精度的浮点类型

7.2.7.double

双精度的浮点类型

7.2.8.date

短日期类型

7.2.9.datetime

长日期类型

7.2.10.clob

字符大对象最多可以存储4G的字符串
比如:存储一个文章,存储一个说明。
超过255个字符的都要采用clob字符大对象来存储
Character Large Object:字符大对象clob

7.2.11.blob

二进制大对象

7.2.12.Binary Large Object

专门用来存储视频,图片,声音等流媒体数据
往BLOB类型的字段上插入数据的时候,例如插入一个图片,视频等。
需要使用IO流才可以。
t_movie 电影表 (专门存储电影信息)

编号名字描述信息上映日期时长海报类型
no(bigint)name(varchar)description(clob)playtime(date)time(double)image(blob)type(char)
1000西游。。。。。2022-10-221.5.。。。。‘1’
1002白发魔女。。。。。2022-10-221.5.。。。。‘2’

7.3 创建一个学生表

create table t_student (no int(3),name varchar(255) , age int(3),sex char(1), email varchar(255) );

7.4 删除一个学生表

#如果这张表不存报错
drop table t_student
#第二种删除 这张表没有的话是不会报错的
drop table if exists t_student;

7.5 往学生表中插入一条记录

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。

7.6 insert 插入日期

数字格式化: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 (小大 小大 小小大)

7.7 date和datetime这两个类型的区别?

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)

7.8 修改update(DML)

语法格式: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)

7.9 删除delete(DML)

语法格式: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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值