【B站老杜】mysql详解(中)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 【B站老杜】mysql详解

2.6 分组查询:group by


什么是分组查询?


在实际的应用中,可能有这样的需求,需要先进行分组,然后对每一组的数据进行操作。


如:


计算每个部门的工资和


计算每个工作岗位的平均薪资


找出每个工作岗位的最高薪资


这个时候我们需要使用分组查询,怎么进行分组查询呢?


关键字的执行顺序


select
  ...
from
  ...
where
  ...
group by
  ...
order by
  ...


结论:select语句中,如果有group by语句,select后面只能跟参加分组的字段,以及分组函数,其它的一律不能跟。


例:找出每个工作岗位的工资和


mysql> select job, sum(sal) from emp group by job order by sal;
+-----------+----------+
| job       | sum(sal) |
+-----------+----------+
| CLERK     |  4150.00 |
| SALESMAN  |  5600.00 |
| MANAGER   |  8275.00 |
| ANALYST   |  6000.00 |
| PRESIDENT |  5000.00 |
+-----------+----------+
5 rows in set (0.00 sec)
mysql> select job, sum(sal) from emp group by job order by sum(sal);
+-----------+----------+
| job       | sum(sal) |
+-----------+----------+
| CLERK     |  4150.00 |
| PRESIDENT |  5000.00 |
| SALESMAN  |  5600.00 |
| ANALYST   |  6000.00 |
| MANAGER   |  8275.00 |
+-----------+----------+
5 rows in set (0.00 sec)


例:找出每个部门的最高薪资


mysql> 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 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.00 sec)
mysql> select * from emp order by deptno;
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME  | JOB       | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
|  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
|  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 |    NULL |     10 |
|  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
|  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
|  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100.00 |    NULL |     20 |
|  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
|  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
|  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800.00 |    NULL |     20 |
|  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
|  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
|  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 |    0.00 |     30 |
|  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
|  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950.00 |    NULL |     30 |
|  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.00 sec)
mysql> select deptno,max(sal) from emp group by deptno;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
|     10 |  5000.00 |
|     20 |  3000.00 |
|     30 |  2850.00 |
+--------+----------+
3 rows in set (0.00 sec)


实例:找出“每个部门,不同工作岗位”的最高薪资


mysql> select deptno,job,max(sal) from emp group by deptno,job;
+--------+-----------+----------+
| deptno | job       | max(sal) |
+--------+-----------+----------+
|     10 | CLERK     |  1300.00 |
|     10 | MANAGER   |  2450.00 |
|     10 | PRESIDENT |  5000.00 |
|     20 | ANALYST   |  3000.00 |
|     20 | CLERK     |  1100.00 |
|     20 | MANAGER   |  2975.00 |
|     30 | CLERK     |   950.00 |
|     30 | MANAGER   |  2850.00 |
|     30 | SALESMAN  |  1600.00 |
+--------+-----------+----------+
9 rows in set (0.00 sec)


1. having


having可以对分完组之后的数据进一步过滤;having必须和group by联合使用。

having不能单独使用,having不能代替where


优化策略:where和having,优先选择where,where实在完成不了了,再选择having。


实例:找出每个部门最高薪资,要求显示最高薪资大于3000的


mysql> select deptno,max(sal) from emp group by deptno;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
|     10 |  5000.00 |
|     20 |  3000.00 |
|     30 |  2850.00 |
+--------+----------+
3 rows in set (0.00 sec)
mysql> select deptno,max(sal) from emp where sal >3000 group by deptno;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
|     10 |  5000.00 |
+--------+----------+
1 row in set (0.00 sec)
mysql> select deptno,max(sal) from emp group by deptno having max(sal)>3000;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
|     10 |  5000.00 |
+--------+----------+
1 row in set (0.00 sec)


无法使用的where的情况:找出每个部门平均薪资,要求显示平均薪资高于2500的。


mysql> select deptno,avg(sal) from emp group by deptno;
+--------+-------------+
| deptno | avg(sal)    |
+--------+-------------+
|     10 | 2916.666667 |
|     20 | 2175.000000 |
|     30 | 1566.666667 |
+--------+-------------+
3 rows in set (0.00 sec)
mysql> select deptno,avg(sal) from emp group by deptno having avg(sal)>2500;
+--------+-------------+
| deptno | avg(sal)    |
+--------+-------------+
|     10 | 2916.666667 |
+--------+-------------+
1 row in set (0.00 sec)


2. 总结


select 
  ...
from
  ...
where
  ...
group by
  ...
having
  ...
order by
  ...


执行顺序?


  1. from


  1. where


  1. group by


  1. having


  1. select


  1. order by


实例:找出每个岗位的平均薪资,要求显示平均薪资大于1500的,除MANAGER岗位之外,要求按照平均薪资降序排。


mysql>  select job,avg(sal) from emp where job <> 'MANAGER' group by job having avg(sal) >1500 order by avg(sal) desc;
mysql>  select job,avg(sal) from emp where job not in ('MANAGER') group by job having avg(sal) >1500 order by avg(sal) desc;
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 |
+-----------+-------------+


3. 去重distinct


注意:原表数据不会被修改,只是查询结果去重


mysql> select job from emp;
+-----------+
| job       |
+-----------+
| CLERK     |
| SALESMAN  |
| SALESMAN  |
| MANAGER   |
| SALESMAN  |
| MANAGER   |
| MANAGER   |
| ANALYST   |
| PRESIDENT |
| SALESMAN  |
| CLERK     |
| CLERK     |
| ANALYST   |
| CLERK     |
+-----------+
14 rows in set (0.00 sec)
mysql> select distinct job from emp;
+-----------+
| job       |
+-----------+
| CLERK     |
| SALESMAN  |
| MANAGER   |
| ANALYST   |
| PRESIDENT |
+-----------+
5 rows in set (0.00 sec)


这样编写是错误的,语法错误:select ename, distinct job from emp;


注意:distinct只能出现在所有字段的最前方


例:distinct出现在job,deptno两个字段之前,表示两个字段联合起来去重


mysql> select job, deptno from emp;
+-----------+--------+
| job       | deptno |
+-----------+--------+
| CLERK     |     20 |
| SALESMAN  |     30 |
| SALESMAN  |     30 |
| MANAGER   |     20 |
| SALESMAN  |     30 |
| MANAGER   |     30 |
| MANAGER   |     10 |
| ANALYST   |     20 |
| PRESIDENT |     10 |
| SALESMAN  |     30 |
| CLERK     |     20 |
| CLERK     |     30 |
| ANALYST   |     20 |
| CLERK     |     10 |
+-----------+--------+
14 rows in set (0.00 sec)
mysql> select distinct job, deptno from emp;
+-----------+--------+
| job       | deptno |
+-----------+--------+
| CLERK     |     20 |
| SALESMAN  |     30 |
| MANAGER   |     20 |
| MANAGER   |     30 |
| MANAGER   |     10 |
| ANALYST   |     20 |
| PRESIDENT |     10 |
| CLERK     |     30 |
| CLERK     |     10 |
+-----------+--------+
9 rows in set (0.00 sec)


例:去除重复之后统计一下工作岗位的数量


mysql> select count(distinct job) from emp;
+---------------------+
| count(distinct job) |
+---------------------+
|                   5 |
+---------------------+
1 row in set (0.01 sec)


2.7 连接查询


1. 连接查询简介


(1)什么是连接查询


从一张表中单独查询,称为单表查询。


emp表和dept表联合起来查询数据,从emp表中取员工名字,从dept表中取部门名字;这种跨表查询,多张表联合起来查询数据,被称为连接查询。


(2)连接查询的分类


根据语法年代的分类


SQL92:1992年的时候出现的语法


SQL99:1999年的时候出现的语法


我们这里重点学习SQL99.(这个过程中简单演示一个SQL92的例子)


根据表连接的方式分类


内连接:等值连接、非等值连接、自连接


外连接:左外连接(左连接)、右外连接(右连接)、全连接(不讲)


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


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


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 |
+--------+--------+
14 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.00 sec)
mysql> select ename, dname from emp,dept;
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | ACCOUNTING |
| SMITH  | RESEARCH   |
| SMITH  | SALES      |
| SMITH  | OPERATIONS |
| ALLEN  | ACCOUNTING |
| ALLEN  | RESEARCH   |
| ALLEN  | SALES      |
| ALLEN  | OPERATIONS |
| WARD   | ACCOUNTING |
| WARD   | RESEARCH   |
| WARD   | SALES      |
| WARD   | OPERATIONS |
| JONES  | ACCOUNTING |
| JONES  | RESEARCH   |
| JONES  | SALES      |
| JONES  | OPERATIONS |
| MARTIN | ACCOUNTING |
| MARTIN | RESEARCH   |
| MARTIN | SALES      |
| MARTIN | OPERATIONS |
| BLAKE  | ACCOUNTING |
| BLAKE  | RESEARCH   |
| BLAKE  | SALES      |
| BLAKE  | OPERATIONS |
| CLARK  | ACCOUNTING |
| CLARK  | RESEARCH   |
| CLARK  | SALES      |
| CLARK  | OPERATIONS |
| SCOTT  | ACCOUNTING |
| SCOTT  | RESEARCH   |
| SCOTT  | SALES      |
| SCOTT  | OPERATIONS |
| KING   | ACCOUNTING |
| KING   | RESEARCH   |
| KING   | SALES      |
| KING   | OPERATIONS |
| TURNER | ACCOUNTING |
| TURNER | RESEARCH   |
| TURNER | SALES      |
| TURNER | OPERATIONS |
| ADAMS  | ACCOUNTING |
| ADAMS  | RESEARCH   |
| ADAMS  | SALES      |
| ADAMS  | OPERATIONS |
| JAMES  | ACCOUNTING |
| JAMES  | RESEARCH   |
| JAMES  | SALES      |
| JAMES  | OPERATIONS |
| FORD   | ACCOUNTING |
| FORD   | RESEARCH   |
| FORD   | SALES      |
| FORD   | OPERATIONS |
| MILLER | ACCOUNTING |
| MILLER | RESEARCH   |
| MILLER | SALES      |
| MILLER | OPERATIONS |
+--------+------------+
56 rows in set (0.00 sec)


最终查询结果条数,是两张表条数的乘积,这种现象被称为:笛卡尔积现象


(4)怎么避免笛卡尔积现象


连接时加条件,满足这个条件的记录被筛选出来


select 
  ename, dname 
from 
  emp, dept
where
  emp.deptno = dept.deptno; 


或者


select 
  emp.ename, dept.dname 
from 
  emp, dept
where
  emp.deptno = dept.deptno;


代码如下:


mysql> select emp.ename, dept.dname from emp, dept where emp.deptno = dept.deptno;
mysql> select e.ename, d.dname from emp e, dept d where e.deptno = d.deptno;  //两个结果一样
+--------+------------+
| ename  | dname      |
+--------+------------+
| CLARK  | ACCOUNTING |
| KING   | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH  | RESEARCH   |
| JONES  | RESEARCH   |
| SCOTT  | RESEARCH   |
| ADAMS  | RESEARCH   |
| FORD   | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| TURNER | SALES      |
| JAMES  | SALES      |
+--------+------------+
14 rows in set (0.01 sec)


思考:最终查询的结果条数是14条,但是匹配的过程中,匹配的次数减少了吗?


还是56次,只不过进行了四选一。次数没有减少。


注意:表的连接次数越多效率越低,所以尽量避免表的连接次数。


2. 内连接:inner


(1)内连接之等值连接


案例:查询每个员工所在部门名称,显示员工名和部门名


SQL92语法


select 
  e.ename,d.dname
from
  emp e, dept d
where
  e.deptno = d.deptno;


sql92的缺点:结构不清晰,表的连接条件,和后期进一步筛选的条件,都放到了where后面。


SQL99语法


inner可以省略(带着inner可读性更好)


mysql> select
    -> e.ename,d.dname
    -> from
    -> emp e
    -> inner join            //inner可以省略
    -> dept d
    -> on
    -> e.deptno = d.deptno;  // 条件是等量关系,所以被称为等值连接。
+--------+------------+
| ename  | dname      |
+--------+------------+
| CLARK  | ACCOUNTING |
| KING   | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH  | RESEARCH   |
| JONES  | RESEARCH   |
| SCOTT  | RESEARCH   |
| ADAMS  | RESEARCH   |
| FORD   | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| TURNER | SALES      |
| JAMES  | SALES      |
+--------+------------+
14 rows in set (0.00 sec)


sql99优点:表连接的条件是独立的,连接之后,如果还需要进一步筛选,再往后继续添加where


  select 
    ...
  from
    a
  join
    b
  on
    a和b的连接条件
  where
    筛选条件


(2)非等值连接


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


select 
  e.ename, e.sal, s.grade
from
  emp e
join
  salgrade s
on
  e.sal between s.losal and s.hisal; // 条件不是一个等量关系,称为非等值连接。


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  | 1600.00 |     3 |
| WARD   | 1250.00 |     2 |
| JONES  | 2975.00 |     4 |
| MARTIN | 1250.00 |     2 |
| BLAKE  | 2850.00 |     4 |
| CLARK  | 2450.00 |     4 |
| SCOTT  | 3000.00 |     4 |
| KING   | 5000.00 |     5 |
| TURNER | 1500.00 |     3 |
| ADAMS  | 1100.00 |     1 |
| JAMES  |  950.00 |     1 |
| FORD   | 3000.00 |     4 |
| MILLER | 1300.00 |     2 |
+--------+---------+-------+
14 rows in set (0.00 sec)


(3)内连接之自连接


实例:查询员工的上级领导,要求显示员工名和对应的领导名


mysql> select empno, ename, mgr from emp limit 5;
+-------+--------+------+
| empno | ename  | mgr  |
+-------+--------+------+
|  7369 | SMITH  | 7902 |
|  7499 | ALLEN  | 7698 |
|  7521 | WARD   | 7698 |
|  7566 | JONES  | 7839 |
|  7654 | MARTIN | 7698 |
+-------+--------+------+
5 rows in set (0.00 sec)


mysql> select a.ename as '员工名', b.ename as '领导名' 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)


以上就是内连接中的:自连接,技巧:一张表看做两张表。


13条记录没有KING,因为KING没有领导


3. 外连接


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


mysql> select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;
+--------+------------+
| ename  | dname      |
+--------+------------+
| CLARK  | ACCOUNTING |
| KING   | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH  | RESEARCH   |
| JONES  | RESEARCH   |
| SCOTT  | RESEARCH   |
| ADAMS  | RESEARCH   |
| FORD   | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| TURNER | SALES      |
| JAMES  | SALES      |
+--------+------------+
14 rows in set (0.00 sec)
mysql> select e.ename,d.dname from emp e right join dept d on e.deptno = d.deptno;
+--------+------------+
| ename  | dname      |
+--------+------------+
| CLARK  | ACCOUNTING |
| KING   | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH  | RESEARCH   |
| JONES  | RESEARCH   |
| SCOTT  | RESEARCH   |
| ADAMS  | RESEARCH   |
| FORD   | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| TURNER | SALES      |
| JAMES  | SALES      |
| NULL   | OPERATIONS |
+--------+------------+
15 rows in set (0.00 sec)


right代表什么:表示将join关键字右边的这张表看成主表,主要是为了将这张表的数据全部查询出来,捎带着关联查询左边的表。在外连接当中,两张表连接,产生了主次关系


(1)(左外连接)


outer是可以省略的,带着可读性强。不管左连接还是右连接的outer都可以省略


select 
  e.ename,d.dname
from
  dept d 
left outer join   //outer可以省略
  emp e
on
  e.deptno = d.deptno;


注意:


  • 带有right的是右外连接,又叫做右连接。


  • 带有left的是左外连接,又叫做左连接。


  • 任何一个右连接都有左连接的写法。


  • 任何一个左连接都有右连接的写法。


思考:外连接的查询结果条数一定是 >= 内连接的查询结果条数的嘛? 正确


实例:查询每个员工的上级领导,要求显示所有员工的名字和领导名


mysql> select a.ename, b.ename from emp a left join emp b on a.mgr=b.empno;
+--------+-------+
| ename  | ename |
+--------+-------+
| 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 |
+--------+-------+
14 rows in set (0.00 sec)


4. 多张表连接


select 
  ...
from
  a
join
  b
on
  a和b的连接条件
join
  c
on
  a和c的连接条件
right join
  d
on
  a和d的连接条件


一条SQL中内连接和外连接可以混合。都可以出现!


案例:找出每个员工的部门名称以及工资等级,要求显示员工名、部门名、薪资、薪资等级


mysql> 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 |
+-------+--------+-----------+------+------------+---------+---------+--------+


mysql> select * from salgrade;
+-------+-------+-------+
| GRADE | LOSAL | HISAL |
+-------+-------+-------+
|     1 |   700 |  1200 |
|     2 |  1201 |  1400 |
|     3 |  1401 |  2000 |
|     4 |  2001 |  3000 |
|     5 |  3001 |  9999 |
+-------+-------+-------+


mysql> select * from dept;
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+


mysql> select e.ename, e.sal, d.dname, 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  | sal     | dname      | grade |
+--------+---------+------------+-------+
| SMITH  |  800.00 | RESEARCH   |     1 |
| ALLEN  | 1600.00 | SALES      |     3 |
| WARD   | 1250.00 | SALES      |     2 |
| JONES  | 2975.00 | RESEARCH   |     4 |
| MARTIN | 1250.00 | SALES      |     2 |
| BLAKE  | 2850.00 | SALES      |     4 |
| CLARK  | 2450.00 | ACCOUNTING |     4 |
| SCOTT  | 3000.00 | RESEARCH   |     4 |
| KING   | 5000.00 | ACCOUNTING |     5 |
| TURNER | 1500.00 | SALES      |     3 |
| ADAMS  | 1100.00 | RESEARCH   |     1 |
| JAMES  |  950.00 | SALES      |     1 |
| FORD   | 3000.00 | RESEARCH   |     4 |
| MILLER | 1300.00 | ACCOUNTING |     2 |
+--------+---------+------------+-------+
14 rows in set (0.00 sec)


5. 子查询


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


子查询都可以出现在哪里呢?


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


(1)where子句中的子查询


案例:找出比最低工资高的员工姓名和工资


mysql> select ename,sal from emp where sal>min(sal);
ERROR 1111 (HY000): Invalid use of group function


错误原因:where子句中不能直接使用分组函数。


实现思路:


第一步:查询最低工资是多少


mysql> select ename, min(sal) from emp;
+-------+----------+
| ename | min(sal) |
+-------+----------+
| SMITH |   800.00 |
+-------+----------+
1 row in set (0.00 sec)


第二步:找出大于800的


mysql> select sal from emp where sal > 800;
+---------+
| sal     |
+---------+
| 1600.00 |
| 1250.00 |
| 2975.00 |
| 1250.00 |
| 2850.00 |
| 2450.00 |
| 3000.00 |
| 5000.00 |
| 1500.00 |
| 1100.00 |
|  950.00 |
| 3000.00 |
| 1300.00 |
+---------+


第三步合并:


mysql> select ename,sal from emp where sal>(select min(sal) from emp);
+--------+---------+
| ename  | sal     |
+--------+---------+
| ALLEN  | 1600.00 |
| WARD   | 1250.00 |
| JONES  | 2975.00 |
| MARTIN | 1250.00 |
| BLAKE  | 2850.00 |
| CLARK  | 2450.00 |
| SCOTT  | 3000.00 |
| KING   | 5000.00 |
| TURNER | 1500.00 |
| ADAMS  | 1100.00 |
| JAMES  |  950.00 |
| FORD   | 3000.00 |
| MILLER | 1300.00 |
+--------+---------+
13 rows in set (0.00 sec)


(2)from子句中的子查询


注意:from后面的子查询,可以将子查询的查询结果当做一张临时表。(技巧)


案例:找出每个岗位的平均工资的薪资等级。


mysql> 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.00 sec)


第一步:找出每个工作岗位的平均工资


mysql> select avg(sal) from emp group by job;
+-------------+
| avg(sal)    |
+-------------+
| 3000.000000 |
| 1037.500000 |
| 2758.333333 |
| 5000.000000 |
| 1400.000000 |
+-------------+
5 rows in set (0.00 sec)


第二步:克服心理障碍,把以上的查询结果就当做一张真实存在的表t。


mysql> select t.*, s.grade from t join salgrade s on t.avg(sal) between s.losal and s.hisal;
ERROR 1146 (42S02): Table 'bjpowernode.t' doesn't exist


mysql> select t.*, s.grade
    -> from (select job,avg(sal) as avgsal from emp group by job) t
    -> join salgrade s
    -> on t.avgsal between s.losal and s.hisal;
+-----------+-------------+-------+
| job       | avgsal      | grade |
+-----------+-------------+-------+
| CLERK     | 1037.500000 |     1 |
| SALESMAN  | 1400.000000 |     2 |
| ANALYST   | 3000.000000 |     4 |
| MANAGER   | 2758.333333 |     4 |
| PRESIDENT | 5000.000000 |     5 |
+-----------+-------------+-------+
5 rows in set (0.00 sec)


(3)select后面出现的子查询(这个内容不需要掌握,了解即可!!!)


实例:找出每个员工的部门名称,要求显示员工名,部门名


mysql> select e.ename, (select d.dname from dept d where e.deptno=d.deptno) as dname from emp e;
+--------+------------+
| 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 |
+--------+------------+
14 rows in set (0.00 sec)


6. 合并查询:union


案例:查询工作岗位是MANAGER和SALESMAN的员工


mysql> select ename, job from emp where job='MANAGER' or job='SALESMAN';
mysql> select ename,job from emp where job in ('MANAGER', 'SALESMAN');
mysql> select ename, job from emp where job='MANAGER'
    -> union
    -> select ename, job from emp where job='SALESMAN';   //三条语句结果一样
+--------+----------+
| ename  | job      |
+--------+----------+
| ALLEN  | SALESMAN |
| WARD   | SALESMAN |
| JONES  | MANAGER  |
| MARTIN | SALESMAN |
| BLAKE  | MANAGER  |
| CLARK  | MANAGER  |
| TURNER | SALESMAN |
+--------+----------+
7 rows in set (0.01 sec)


union的效率要高一些。对于表连接来说,每连接一次新表,则匹配的次数满足笛卡尔积,成倍的翻…


但是union可以减少匹配的次数。在减少匹配次数的情况下,还可以完成两个结果集的拼接。


比如:


a 连接 b 连接 c


a 10条记录


b 10条记录


c 10条记录


匹配次数是:1000


a 连接 b一个结果:10 * 10 --> 100次


a 连接 c一个结果:10 * 10 --> 100次


使用union的话是:100次 + 100次 = 200次。(union把乘法变成了加法运算)


注意事项:


错误:union在进行结果集合并的时候,要求两个结果集的列数相同。


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


MYSQL可以,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  | 1600    |
| WARD   | 1250    |
| MARTIN | 1250    |
| TURNER | 1500    |
+--------+---------+


7. 分页函数:limit


作用:显示部分查询结果,通常使用在分页查询当中。


完整用法:limit startIndex, length


实例:按照薪资降序,取出排名在前5名的员工


mysql> select ename,sal from emp order by sal desc limit 5;
mysql> select ename,sal from emp order by sal desc limit 0,5;   //第一个参数为起始索引,默认从0开始  第二个参数为长度
+-------+---------+
| ename | sal     |
+-------+---------+
| KING  | 5000.00 |
| SCOTT | 3000.00 |
| FORD  | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
5 rows in set (0.01 sec)


注意:mysql当中limit在order by之后执行!


实例:取出工资排名在[3-5]名的员工


mysql> select ename,sal from emp order by sal desc limit 2,3;  //下标2开始,长度为3
+-------+---------+
| ename | sal     |
+-------+---------+
| FORD  | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
3 rows in set (0.00 sec)


分页


每页显示3条记录


第1页:limit 0,3


第2页:limit 3,3


第3页:limit 6,3


第4页:limit 9,3


第pageNo页:limit (pageNo - 1) * pageSize , pageSize


2.8 DQL语句的总结


select 
  ...
from
  ...
where
  ...
group by
  ...
having
  ...
order by
  ...
limit
  ...


第3章 DDL语言:数据定义语言


DDL:数据定义语言:create(增)、drop(删)、alter(改)、truncate。主要是对表结构进行操作。


3.1 MySQL的数据类型


类型 作用
varchar 可变长的字符串类型,根据实际长度东忒分配空间。优点:节省空间。缺点:需要动态分配空间,速度慢。最长255
char 定长字符串类型, 不管实际的数据长度是多少,分配固定长度的空间去存储数据。优缺点与上面相反。最长255
int 整型。等同于java的int。最长11
bigint 长整型。等同于java中的long。
float 单精度浮点型
double 双精度浮点型
date 短日期类型
datetime 长日期类型
clob Character Large OBject:CLOB。字符大对象, 最多存储4G的字符串。 超过255个字符的采用CLOB存储。 比如:存储一篇文章,一篇说明。
blob Binary Large OBject; 二进制大对象, 用来存储图片、声音、视频等流媒体数据。 BLOB类型字段上插入数据时,需要使用IO流。


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


性别字段选:性别是固定长度字符串,选择char。


姓名字段选:每个人名字长度不同,选择varchar。


例如:t_movie 电影表,存储电影信息


编号         名字     故事情节        上映日期         时长       海报        类型
no(bigint)  name(varchar) history(clob)   playtime(date)    time(double)  image(blob)     type(char)
------------------------------------------------------------------------------------------------------------------
10000      哪吒       ..........        2019-10-11       2.5         ....        '1'
10001      悟空传         ..........          2019-11-11       1.5        ....         '2'
....


3.2 表的创建:create


建表的语法格式create table 表名(字段名1 数据类型, 字段名2 数据类型, 字段名3 数据类型);


create table 表名(
  字段名1 数据类型, 
  字段名2 数据类型, 
  字段名3 数据类型
);


表名:建议以t_ 或者 tbl_开始,可读性强。见名知意。


字段名:见名知意。


表名和字段名都属于标识符。


3.3 表的删除:drop


drop table t_student;             //注意:当这张表不存在的时候会报错!
drop table if exists t_student;   //两句都可以,推荐这句


实例:创建一个学生表,学号、姓名、年龄、性别、邮箱地址


mysql> create table t_student(
    -> no int,
    -> name varchar(32),
    -> sex char(1),
    -> age int(3),
    -> email varchar(255)
    -> );
Query OK, 0 rows affected (0.01 sec)


3.4 快速创建表


了解内容, 将查询结果当做一张表新建,实现表集数据的快速复制


mysql> create table emp2 as select * from emp;  //两张表的数据一模一样
Query OK, 14 rows affected (0.01 sec)
Records: 14  Duplicates: 0  Warnings: 0


mysql> create table mytable as select empno,ename from emp where job='MANAGER';
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> select * from mytable;
+-------+-------+
| empno | ename |
+-------+-------+
|  7566 | JONES |
|  7698 | BLAKE |
|  7782 | CLARK |
+-------+-------+
3 rows in set (0.00 sec)


3.5 快速删除表中的数据:truncate


delete from dept_bak;      //这种删除数据的方式比较慢。


delete原理: 表中数据被删除了,但是数据在硬盘上的真实存储空间不会被释放!


缺点:删除效率比较低; 优点:支持回滚(即可恢复)


回滚实例


mysql> select * from dept_bak;
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
4 rows in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from dept_bak;
Query OK, 4 rows affected (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from dept_bak;
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
4 rows in set (0.00 sec)


truncate原理:表被一次截断,物理删除。


缺点:不支持回滚。 优点:效率高,快速。


语法:truncate table dept_bak;


mysql> truncate table dept_bak;          //删数据,不是删表
Query OK, 0 rows affected (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from dept_bak;          //回滚也没用
Empty set (0.00 sec)


truncate删除速度很快,但是数据不可恢复。


注意:truncate是删除表中的数据,表还在。删除表用drop


3.6 修改表结构:alter


意思:添加一个字段,删除一个字段,修改一个字段!!!


第一:实际开发中,需求一旦确定,表一旦设计完成,很少对表结构修改。因为开发进行中修改结果成本较高,对应的java代码需要进行大量修改。这个责任应该由设计人员来承担!


第二:由于修改表结构操作很少,我们不需要掌握,如果真要修改,可以使用工具!


修改表结构操作不需要写到java程序中,也不是java程序员的范畴。


第4章 DML语言:数据操作语言


DML:数据操作语言:insert(增)、update(删)、delete(改)。主要是操作表中数据的操作


4.1 DML增:insert


语法格式:insert into 表名(字段名1,字段名2,字段名3…) values(值1,值2,值3);


注意:字段名和值要一一对应,即数量要对应。数据类型要对应。


mysql> insert into t_student(no,name,sex,age,email) values(1,'zhangsan','m',20,'zhangsan@123.com');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_student;
+------+----------+------+------+------------------+
| no   | name     | sex  | age  | email            |
+------+----------+------+------+------------------+
|    1 | zhangsan | m    |   20 | zhangsan@123.com |
+------+----------+------+------+------------------+
1 row in set (0.00 sec)


mysql> insert into t_student(email,name,sex,age,no) values('lisi@123.com','lisi','m',22,2);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_student;
+------+----------+------+------+------------------+
| no   | name     | sex  | age  | email            |
+------+----------+------+------+------------------+
|    1 | zhangsan | m    |   20 | zhangsan@123.com |
|    2 | lisi     | m    |   22 | lisi@123.com     |
+------+----------+------+------+------------------+
2 rows in set (0.00 sec)


mysql> insert into t_student(no) values(3);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_student;
+------+----------+------+------+------------------+
| no   | name     | sex  | age  | email            |
+------+----------+------+------+------------------+
|    1 | zhangsan | m    |   20 | zhangsan@123.com |
|    2 | lisi     | m    |   22 | lisi@123.com     |
|    3 | NULL     | NULL | NULL | NULL             |
+------+----------+------+------+------------------+
3 rows in set (0.00 sec)


mysql> insert into t_student(name) values('wangwu');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_student;
+------+----------+------+------+------------------+
| no   | name     | sex  | age  | email            |
+------+----------+------+------+------------------+
|    1 | zhangsan | m    |   20 | zhangsan@123.com |
|    2 | lisi     | m    |   22 | lisi@123.com     |
|    3 | NULL     | NULL | NULL | NULL             |
| NULL | wangwu   | NULL | NULL | NULL             |
+------+----------+------+------+------------------+
4 rows in set (0.00 sec)


注意:insert语句执行成功,必然多一条记录。若没有给定其它字段值,默认为NULL。


(1)设置默认值:defalut


drop table if exists t_student;
create table t_student(
    no int,
    name varchar(32),
    sex char(1) default 'm',   //default设置默认值   默认性别:'m'
    age int(3),
    email varchar(255)
    );


查看表的数据类型


mysql> desc t_student;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| no    | int(11)      | YES  |     | NULL    |       |
| name  | varchar(32)  | YES  |     | NULL    |       |
| sex   | char(1)      | YES  |     | m       |       |
| age   | int(3)       | YES  |     | NULL    |       |
| email | varchar(255) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
5 rows in set (0.01 sec)


mysql> insert t_student(no) values(1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_student;
+------+------+------+------+-------+
| no   | name | sex  | age  | email |
+------+------+------+------+-------+
|    1 | NULL | m    | NULL | NULL  |
+------+------+------+------+-------+
1 row in set (0.00 sec)
mysql> insert into t_student values(2);
ERROR 1136 (21S01): Column count doesn't match value count at row 1


注意:前面字段名省略的话,等于都写上了!所以值也要都写上!


mysql> insert into t_student values(2);
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> insert into t_student values(2, 'lisi', 'f', 20, 'lisi@123.com');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_student;
+------+------+------+------+--------------+
| no   | name | sex  | age  | email        |
+------+------+------+------+--------------+
|    1 | NULL | m    | NULL | NULL         |
|    2 | lisi | f    |   20 | lisi@123.com |
+------+------+------+------+--------------+
2 rows in set (0.00 sec)


(2)数字格式化:format()函数


格式:format(数字, ‘格式’)


mysql> select ename,sal from emp limit 5;
+--------+---------+
| ename  | sal     |
+--------+---------+
| SMITH  |  800.00 |
| ALLEN  | 1600.00 |
| WARD   | 1250.00 |
| JONES  | 2975.00 |
| MARTIN | 1250.00 |
+--------+---------+
5 rows in set (0.00 sec)
mysql> select ename, format(sal,'$999,999') as sal from emp limit 5;
+--------+-------+
| ename  | sal   |
+--------+-------+
| SMITH  | 800   |
| ALLEN  | 1,600 |
| WARD   | 1,250 |
| JONES  | 2,975 |
| MARTIN | 1,250 |
+--------+-------+
5 rows in set, 5 warnings (0.00 sec)


(3)插入日期:str_to_date()


str_to_date:将varchar类型转换成date类型


date_format:将date类型转换成varchar类型


注意:标识符全部小写,单词之间使用下划线。


drop table if exists t_user;                  //删除表
create table t_user(                          //重新创建表
    id int,
    name varchar(32),
    birth date
    );


mysql> desc t_user;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(32) | YES  |     | NULL    |       |
| birth | date        | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> insert into  t_user(id,name,birth) values(1,'zs','01-10-1990');  //插入数据
ERROR 1292 (22007): Incorrect date value: '01-10-1990' for column 'birth' at row 1


出问题了:原因是类型不匹配。数据库birth是date类型,这里给了一个字符串varchar。


可以使用str_to_date函数进行类型转换,将字符串转换成日期类型date


语法格式:str_to_date('字符串日期', '日期格式')


mysql的日期格式


  %Y  年
  %m  月
  %d  日
  %h  时
  %i  分
  %s  秒


mysql> insert into  t_user(id,name,birth) values(1,'zs',str_to_date('01-10-1990','%d-%m-%Y'));
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_user;
+------+------+------------+
| id   | name | birth      |
+------+------+------------+
|    1 | zs   | 1990-10-01 |
+------+------+------------+
1 row in set (0.00 sec)


str_to_date函数把字符串varchar转换成日期date类型,通常在插入insert时使用

注意:如果你提供的日期字符串是这个格式:%Y-%m-%d,可以直接插入,str_to_date函数就不需要了


mysql> insert into t_user(id,name,birth) values(2, 'lisi', '1990-10-01');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_user;
+------+------+------------+
| id   | name | birth      |
+------+------+------------+
|    1 | zs   | 1990-10-01 |
|    2 | lisi | 1990-10-01 |
+------+------+------------+
2 rows in set (0.00 sec)


查询的时候可以以某个特定的日期格式展示。date_format函数将日期类型转换成特定格式的字符串。


语法: date_format(日期类型数据, ‘日期格式’)


mysql>  select id,name,date_format(birth,'%m/%d/%y') as birth from t_user;
+------+------+----------+
| id   | name | birth    |
+------+------+----------+
|    1 | zs   | 10/01/90 |
|    2 | lisi | 10/01/90 |
+------+------+----------+
2 rows in set (0.00 sec)


mysql> select id,name,birth from t_user;
    +------+----------+------------+
    | id   | name     | birth      |
    +------+----------+------------+
    |    1 | zhangsan | 1990-10-01 |
    |    2 | lisi     | 1990-10-01 |
    +------+----------+------------+


以上语句进行了默认格式转换,自动将数据库中的date类型转换成varchar类型。默认的日期格式:’%Y-%m-%d’


(4)date和datetime类型区别


date是短日期:只包括年月日信息。


datetime是长日期:包括年月日时分秒信息。


mysql短日期默认格式:%Y-%m-%d


mysql长日期默认格式:%Y-%m-%d %h:%i:%s


mysql> create table t_user(     //创建表
    -> id int,
    -> name varchar(32),
    -> birth date,
    -> create_time datetime    //长日期类型
    -> );
Query OK, 0 rows affected (0.01 sec)
mysql> insert into t_user(id,name,birth,create_time) values(1,'zhangsan','1990-10-01','2021-09-14 15:49:50');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t_user values(1,'zhangsan','1990-10-01','2021-09-14 15:49:50');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_user;
+------+----------+------------+---------------------+
| id   | name     | birth      | create_time         |
+------+----------+------------+---------------------+
|    1 | zhangsan | 1990-10-01 | 2021-09-14 15:49:50 |
|    1 | zhangsan | 1990-10-01 | 2021-09-14 15:49:50 |
+------+----------+------------+---------------------+
2 rows in set (0.00 sec)


(5)获取系统当前时间:new()


now() 函数获取的时间带有时分秒信息!是datetime类型。


mysql> insert into t_user values(3,'lisi','1990-10-01',now());
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_user;
+------+----------+------------+---------------------+
| id   | name     | birth      | create_time         |
+------+----------+------------+---------------------+
|    1 | zhangsan | 1990-10-01 | 2021-09-14 15:49:50 |
|    1 | zhangsan | 1990-10-01 | 2021-09-14 15:49:50 |
|    3 | lisi     | 1990-10-01 | 2021-11-25 15:50:02 |
+------+----------+------------+---------------------+
3 rows in set (0.00 sec)


(6)一次插入多条数据


语法insert into t_user(字段名1,字段名2) values(), (), (), ();


mysql> insert into t_user values
    -> (1, 'zs', '1980-10-11', now()),
    -> (2, 'ls', '1981-10-11', now()),
    -> (3, 'ww', '1982-10-11', now());
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> select * from t_user;
+------+------+------------+---------------------+
| id   | name | birth      | create_time         |
+------+------+------------+---------------------+
|    1 | zs   | 1980-10-11 | 2021-11-29 20:55:54 |
|    2 | ls   | 1981-10-11 | 2021-11-29 20:55:54 |
|    3 | ww   | 1982-10-11 | 2021-11-29 20:55:54 |
+------+------+------------+---------------------+
3 rows in set (0.00 sec)


(7)select查询结果插入表


用insert将查询到的结果插入表中,很少用到(了解内容


drop table if exists dept_bak;                 //删除表
create table dept_bak as select * from dept;   //创建表


mysql> select * from dept_bak;
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
4 rows in set (0.00 sec)
mysql> insert into dept_bak select * from dept;
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0
mysql> select * from dept_bak;
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
8 rows in set (0.00 sec)


4.2 DML改:update


语法格式:update 表名 set 字段名1=值1,字段名2=值2,字段名3=值3… where 条件;


注意:没有条件限制会导致所有数据全部更新。


mysql> update t_user set name = 'jack',birth = '2000-10-11' where id = 3;  //修改id=3的数据
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> select * from t_user;
+------+----------+------------+---------------------+
| id   | name     | birth      | create_time         |
+------+----------+------------+---------------------+
|    1 | zhangsan | 1990-10-01 | 2021-09-14 15:49:50 |
|    1 | zhangsan | 1990-10-01 | 2021-09-14 15:49:50 |
|    3 | jack     | 2000-10-11 | 2021-11-25 15:50:02 |
+------+----------+------------+---------------------+
mysql> update t_user set create_time = now() where id =1;   //修改id=1的数据
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2  Changed: 2  Warnings: 0
mysql> select * from t_user;
+------+----------+------------+---------------------+
| id   | name     | birth      | create_time         |
+------+----------+------------+---------------------+
|    1 | zhangsan | 1990-10-01 | 2021-11-25 15:54:20 |
|    1 | zhangsan | 1990-10-01 | 2021-11-25 15:54:20 |
|    3 | jack     | 2000-10-11 | 2021-11-25 15:50:02 |
+------+----------+------------+---------------------+
3 rows in set (0.00 sec)


4.3 DML删:delete


语法格式: delete from 表名 where 条件;


注意:没有条件,整张表的数据会全部删除!


mysql> delete from t_user where id = 3;   //删除id=3的数据
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_user;
+------+----------+------------+---------------------+
| id   | name     | birth      | create_time         |
+------+----------+------------+---------------------+
|    1 | zhangsan | 1990-10-01 | 2021-11-25 15:54:20 |
|    1 | zhangsan | 1990-10-01 | 2021-11-25 15:54:20 |
+------+----------+------------+---------------------+
2 rows in set (0.00 sec)
mysql> insert into t_user(id) values(2);   //插
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_user;
+------+----------+------------+---------------------+
| id   | name     | birth      | create_time         |
+------+----------+------------+---------------------+
|    1 | zhangsan | 1990-10-01 | 2021-11-25 15:54:20 |
|    1 | zhangsan | 1990-10-01 | 2021-11-25 15:54:20 |
|    2 | NULL     | NULL       | NULL                |
+------+----------+------------+---------------------+
3 rows in set (0.00 sec)
mysql> delete from t_user;             //删全表
Query OK, 3 rows affected (0.01 sec)
mysql> select * from t_user;
Empty set (0.00 sec)
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
6月前
|
SQL 关系型数据库 MySQL
(B站动力节点老杜MySQL教程)MySQL课堂笔记-day01.txt
(B站动力节点老杜MySQL教程)MySQL课堂笔记-day01.txt
|
SQL 关系型数据库 MySQL
跟着老杜学习MySql--day2(下)
跟着老杜学习MySql--day2(下)
11218 1
|
数据处理 数据库
跟着老杜学习MySQL--day1(中)
跟着老杜学习MySQL--day1(中)
369 0
|
SQL 存储 Oracle
跟着老杜学习MySql--day2(中)
跟着老杜学习MySql--day2(中)
376 0
|
SQL 关系型数据库 MySQL
跟着老杜学习MySql--day2(上)
跟着老杜学习MySql--day2(上)
50 0
|
SQL Oracle 关系型数据库
跟着老杜学习MySQL--day1(下)
跟着老杜学习MySQL--day1(下)
341 0
|
SQL 存储 Oracle
跟着老杜学习MySQL--day1(上)
跟着老杜学习MySQL--day1(上)
131 0
|
存储 SQL Oracle
【B站老杜】mysql详解(下)
【B站老杜】mysql详解
721 0
【B站老杜】mysql详解(下)
|
SQL 存储 Oracle
【B站老杜】mysql详解(上)
【B站老杜】mysql详解
137 0
【B站老杜】mysql详解(上)
|
SQL 存储 Oracle
最全面的MySQL数据库教程,老杜带你基础入门mysql
数据库软件里面用的比较多的就MySQL了,对于企业还是个人开发者,或者是学生,都是很好的选择,下面为大家带来MySQL的学习教程,让大家快速入门MySQL数据库,学会安装配置MySQL ,掌握MySQL基本知识,并轻松使用 MySQL 数据库。
1248 0