mysql入门基础总结

1.数据库概述

数据库:DataBase,简称DB,按照一定格式存储数据的一些文件的组合

数据库管理系统:DataBaseManagementSystem,简称DBMS,它专门用来管理数据库中的数据

​ 常见的数据库管理系统:MySQL、Oracle、MS SqlServer、DB2、sybase等

SQL:结构化查询语言

三者之间的关系:DBMS通过执行SQL来操作DB

2.常用命令

本地登录(显式):mysql -uroot -p123456

隐式:mysql -uroot -p

退出mysql:exit

查看mysql中有哪些数据库:show databases;

选择使用哪个数据库:use 数据库名

创建一个数据库:create database 数据库名;

删除一个数据库:drop database 数据库名

查看数据库中的表:show tables;

导入数据:source 路径(不要有中文)

查看表的结构:desc 表名;

查看数据库版本号:select version();

查看当前使用的是哪个数据库:select database();

3.表的理解

数据库中最基本的单元是表:table

任何一张表都有行和列:

行(row):被称为数据/记录

列(column):被称为字段

每一个字段都有字段名、数据类型、约束等属性

4.SQL语句的分类

DQL:数据查询语言 select

DML:数据操作语言 insert delete updata

DDL:数据定义语言 create drop alter

TCL:事务控制语言 commit rollback

DCL:数据控制语言 grant revoke

5.DQL语句

查询两个字段,或者多个字段,使用逗号隔开

select deptno,dname from dept;
+--------+------------+
| deptno | dname      |
+--------+------------+
|     10 | ACCOUNTING |
|     20 | RESEARCH   |
|     30 | SALES      |
|     40 | OPERATIONS |
+--------+------------+

查询所有字段, 使用 * 的缺点,效率低、可读性差

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

给查询的列起别名 as

注意:只是将查询的结果列名显示为deptname,原列名不变 as关键字可以省略

若起的别名有空格,可以使用单引号

select deptno,dname as deptname from dept;
+--------+------------+
| deptno | deptname   |
+--------+------------+
|     10 | ACCOUNTING |
|     20 | RESEARCH   |
|     30 | SALES      |
|     40 | OPERATIONS |
+--------+------------+

查询员工的年薪 字段可以使用数学表达式!

select ename,sal*12 as yearsal from emp;
+--------+----------+
| ename  | aslyear  |
+--------+----------+
| SMITH  |  9600.00 |
| ALLEN  | 19200.00 |
| WARD   | 15000.00 |
| JONES  | 35700.00 |
| MARTIN | 15000.00 |
| BLAKE  | 34200.00 |
| CLARK  | 29400.00 |
| SCOTT  | 36000.00 |
| KING   | 60000.00 |
| TURNER | 18000.00 |
| ADAMS  | 13200.00 |
| JAMES  | 11400.00 |
| FORD   | 36000.00 |
| MILLER | 15600.00 |
+--------+----------+

条件查询

格式:select … from … where 条件;

有哪些条件

= < > <= >= != between…and…(包括两边 遵循左小右大) is null

and or (and和or同时出现and优先级较高,最好加括号)

in (相当于多个or in不是一个区间) not in (表示不在这几个值当中的数据)

select empno,ename,job from emp where job='MANAGER'or job='SALEMAN';
select empno,ename,job from emp where job in('MANAGER','SALEMAN');
+-------+-------+---------+
| empno | ename | job     |
+-------+-------+---------+
|  7566 | JONES | MANAGER |
|  7698 | BLAKE | MANAGER |
|  7782 | CLARK | MANAGER |
+-------+-------+---------+

like称为模糊查询 _ :表示任意一个字符 %:表示任意多个字符 \ 转义字符

select ename from emp where ename like '%o%';
+-------+
| ename |
+-------+
| JONES |
| SCOTT |
| FORD  |
+-------+

排序

select ename,sal from emp order by sal;  //默认升序
select ename,sal from emp order by sal asc; //升序
select ename,sal from emp order by sal desc; //降序
select ename,sal from emp order by sal asc,ename asc;//先按薪资排序,再按名字排序
+--------+---------+
| ename  | sal     |
+--------+---------+
| SMITH  |  800.00 |
| JAMES  |  950.00 |
| ADAMS  | 1100.00 |
| WARD   | 1250.00 |
| MARTIN | 1250.00 |
| MILLER | 1300.00 |
| TURNER | 1500.00 |
| ALLEN  | 1600.00 |
| CLARK  | 2450.00 |
| BLAKE  | 2850.00 |
| JONES  | 2975.00 |
| SCOTT  | 3000.00 |
| FORD   | 3000.00 |
| KING   | 5000.00 |
+--------+---------+
6.数据处理函数

数据处理函数又被称为单行处理函数

单行处理函数的特点:一个输入对应一个输出

select lower(ename) as ename from emp; //lower:转小写    upper:转大写
+--------+
| ename  |
+--------+
| smith  |
| allen  |
| ward   |
| jones  |
| martin |
| blake  |
| clark  |
| scott  |
| king   |
| turner |
| adams  |
| james  |
| ford   |
| miller |
+--------+ //14个输入最后还是14个输出,这是单行处理函数的特点

substr(被截取的字符串,起始下标,截取的长度):取子串 注意:起始下标从1开始

select ename from emp where substr(ename,1,1)='A'; 
+-------+
| ename |
+-------+
| ALLEN |
| ADAMS |
+-------+

首字符大写 length(name):取长度 concat( , ):拼接

select concat(upper(substr(ename,1,1)),lower(substr(ename,2,length(ename) - 1))) as result from emp;
+--------+
| result |
+--------+
| Smith  |
| Allen  |
| Ward   |
| Jones  |
| Martin |
| Blake  |
| Clark  |
| Scott  |
| King   |
| Turner |
| Adams  |
| James  |
| Ford   |
| Miller |
+--------+

trim:去空格

select * from emp where ename=trim(' King');
+-------+-------+-----------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB       | MGR  | HIREDATE   | SAL     | COMM | DEPTNO |
+-------+-------+-----------+------+------------+---------+------+--------+
|  7839 | KING  | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL |     10 |
+-------+-------+-----------+------+------------+---------+------+--------+

round 四舍五入

select round(1236.567,1) as result from emp; //保留一个小数
+--------+
| result |
+--------+
| 1236.6 |
| 1236.6 |
| 1236.6 |
| 1236.6 |
| 1236.6 |
| 1236.6 |
| 1236.6 |
| 1236.6 |
| 1236.6 |
| 1236.6 |
| 1236.6 |
| 1236.6 |
| 1236.6 |
| 1236.6 |
+--------+

rand 生成随机数

select rand() from emp;
+---------------------+
| rand()              |
+---------------------+
|  0.3012791874830417 |
| 0.28756545045186344 |
|  0.5339897205438369 |
|  0.8072522820972393 |
|  0.4342922795883308 |
|  0.7497045823835811 |
| 0.44564610388655784 |
|   0.979116803015691 |
|  0.5586457341524267 |
|  0.8558782924487053 |
|  0.6034542905198915 |
| 0.44963660598698685 |
| 0.43782018910890463 |
|  0.8401911583172075 |
+---------------------+

select round(rand()*100,0) from emp;  //100以内的随机数
+---------------------+
| round(rand()*100,0) |
+---------------------+
|                  83 |
|                  72 |
|                  10 |
|                  36 |
|                  49 |
|                  36 |
|                  32 |
|                  54 |
|                  72 |
|                  99 |
|                  77 |
|                  91 |
|                  24 |
|                  45 |
+---------------------+

ifnull 可以将null转换成一个具体值

ifnull是空处理函数,专门用来处理空的

在所有数据库当中,只要有NULL参与的数学运算,最终结果就是NULL

select ename,sal+comm as salcomm from emp;
+--------+---------+
| ename  | salcomm |
+--------+---------+
| SMITH  |    NULL |
| ALLEN  | 1900.00 |
| WARD   | 1750.00 |
| JONES  |    NULL |
| MARTIN | 2650.00 |
| BLAKE  |    NULL |
| CLARK  |    NULL |
| SCOTT  |    NULL |
| KING   |    NULL |
| TURNER | 1500.00 |
| ADAMS  |    NULL |
| JAMES  |    NULL |
| FORD   |    NULL |
| MILLER |    NULL |
+--------+---------+

ifnull(数据,被当作那个值)

select ename,(sal+ifnull(comm,0))*12 as yearsal from emp;
+--------+----------+
| ename  | yearsal  |
+--------+----------+
| SMITH  |  9600.00 |
| ALLEN  | 22800.00 |
| WARD   | 21000.00 |
| JONES  | 35700.00 |
| MARTIN | 31800.00 |
| BLAKE  | 34200.00 |
| CLARK  | 29400.00 |
| SCOTT  | 36000.00 |
| KING   | 60000.00 |
| TURNER | 18000.00 |
| ADAMS  | 13200.00 |
| JAMES  | 11400.00 |
| FORD   | 36000.00 |
| MILLER | 15600.00 |
+--------+----------+

case when then when then else end (不修改数据库)

select ename,job,sal as oldsal,
(case job when 'MANAGER' then sal*1.1 when 'SALESMAN' then sal*1.5 else sal end) 
as newsal 
from emp;
+--------+-----------+---------+---------+
| ename  | job       | oldsal  | newsal  |
+--------+-----------+---------+---------+
| SMITH  | CLERK     |  800.00 |  800.00 |
| ALLEN  | SALESMAN  | 1600.00 | 2400.00 |
| WARD   | SALESMAN  | 1250.00 | 1875.00 |
| JONES  | MANAGER   | 2975.00 | 3272.50 |
| MARTIN | SALESMAN  | 1250.00 | 1875.00 |
| BLAKE  | MANAGER   | 2850.00 | 3135.00 |
| CLARK  | MANAGER   | 2450.00 | 2695.00 |
| SCOTT  | ANALYST   | 3000.00 | 3000.00 |
| KING   | PRESIDENT | 5000.00 | 5000.00 |
| TURNER | SALESMAN  | 1500.00 | 2250.00 |
| ADAMS  | CLERK     | 1100.00 | 1100.00 |
| JAMES  | CLERK     |  950.00 |  950.00 |
| FORD   | ANALYST   | 3000.00 | 3000.00 |
| MILLER | CLERK     | 1300.00 | 1300.00 |
+--------+-----------+---------+---------+
7.分组函数

分组函数(多行处理函数)的特点:多个输入对应一个输出

分组函数在使用时必须先进行分组,如果没有对数据分组,则整张表默认为一组

注意:

①分组函数自动忽略null

②count(*):表示统计表中所有的行数

count(字段):表示统计该字段下所有不为null元素的总数

③分组函数不能直接使用在where子句中

④所有的分组函数可以组合起来一起用

count计数

select count(ename) from emp;
+--------------+
| count(ename) |
+--------------+
|           14 |
+--------------+

sum求和

select sum(comm) from emp;
+-----------+
| sum(comm) |
+-----------+
|   2200.00 |
+-----------+

avg平均值

select round(avg(sal),-1) as avg from emp;
+------+
| avg  |
+------+
| 2070 |
+------+

max最大值

select max(sal) from emp;
+----------+
| max(sal) |
+----------+
|  5000.00 |
+----------+

min最小值

select min(sal) from emp;
+----------+
| min(sal) |
+----------+
|   800.00 |
+----------+
8.分组查询

select … from … where … group by … having … order by …

执行顺序:①from②where③group by④having⑤select⑥order by

分组函数不能直接使用在where之后

找出每个岗位的工资和

select job,sum(sal) from emp group by job;
+-----------+----------+
| job       | sum(sal) |
+-----------+----------+
| ANALYST   |  6000.00 |
| CLERK     |  4150.00 |
| MANAGER   |  8275.00 |
| PRESIDENT |  5000.00 |
| SALESMAN  |  5600.00 |
+-----------+----------+

重要结论:在一条select语句当中,如果有group by语句的话,select后面只能跟参加分组的字段以及分组函数

select deptno,max(sal) from emp group by deptno;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
|     10 |  5000.00 |
|     20 |  3000.00 |
|     30 |  2850.00 |
+--------+----------+

找出每个部门,不同工作岗位的最高薪资 (两个字段联合分组)

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

使用having可以对分完组之后的数据进行进一步过滤

having不能单独使用,having不能代替where,having必须要和group by联合使用

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

select deptno,max(sal) from emp group by deptno having max(sal)>3000;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
|     10 |  5000.00 |
+--------+----------+

思考一下以上sql语句执行效率是不是低?

select deptno,max(sal) from emp where sal>3000 group by deptno;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
|     10 |  5000.00 |
+--------+----------+

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

找出每个部门的平均薪资,要求显示平均薪资高于2500的

select deptno,avg(sal) from emp group by deptno having avg(sal)>2500;
+--------+-------------+
| deptno | avg(sal)    |
+--------+-------------+
|     10 | 2916.666667 |
+--------+-------------+
9.distinct
select distinct job from emp;
+-----------+
| job       |
+-----------+
| CLERK     |
| SALESMAN  |
| MANAGER   |
| ANALYST   |
| PRESIDENT |
+-----------+

select ename,distinct job from emp; //语法错误

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

统计工作岗位的数量

select count(distinct job) from emp;
+---------------------+
| count(distinct job) |
+---------------------+
|                   5 |
+---------------------+
10.连接查询

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

多张表连接起来查询数据,叫做连接查询

根据表连接的方式分类:

内连接:

等值连接

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

select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno; //sql92语法
+--------+------------+
| 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 |
+--------+------------+
select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;//sql99语法
+--------+------------+
| 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 |
+--------+------------+

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

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

非等值连接

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

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

自连接

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

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

外连接:

左外连接(左连接)

select e.ename,d.dname from dept d left join emp e 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 |
| NULL   | OPERATIONS |
+--------+------------+

表示将join关键字左边的这张表看成主表,将这张表的数据全部查询出来,捎带着关联查询右边的表

右外连接(右连接)

select e.ename,d.dname from emp e right 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 |
| NULL   | OPERATIONS |
+--------+------------+

表示将join关键字右边的这张表看成主表,将这张表的数据全部查询出来,捎带着关联查询左边的表

三张表、四张表怎么连接?

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

一条sql中内连接和外连接可以混合

全连接

两张表连接没有任何条件限制,最终查询结果的条数是两张表条数的乘积

select ename,dname from emp,dept;  //笛卡尔积现象
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | ACCOUNTING |
| SMITH  | RESEARCH   |
| SMITH  | SALES      |
| SMITH  | OPERATIONS |
| ALLEN  | ACCOUNTING |
| ALLEN  | RESEARCH   |
| ALLEN  | SALES      |
| ALLEN  | OPERATIONS |
| MILLER | ACCOUNTING |
| MILLER | RESEARCH   |
| MILLER | SALES      |
| MILLER | OPERATIONS |
+--------+------------+

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

select ename,dname from emp,dept where emp.deptno=dept.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 |
+--------+------------+

注意:最终查询的结果条数是14条,但是匹配的过程中,匹配的次数没有减少

起别名:

select

​ e.ename,d.dname

from

​ emp e,dept d

where

​ e.deptno=d.deptno; //92语法

select e.ename,d.dname from emp e,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 |
+--------+------------+

通过笛卡尔现象得出,表的连接次数越多效率越低,尽量避免表的连接次数

11.子查询

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

select  //子查询都可以出现在哪里
	...(select)
from
	...(select)
where
	...(select)

where中的子查询

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

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

from中的子查询

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

找出每个岗位的平均工资的薪资等级

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 |
+-----------+-------------+-------+
| ANALYST   | 3000.000000 |     4 |
| CLERK     | 1037.500000 |     1 |
| MANAGER   | 2758.333333 |     4 |
| PRESIDENT | 5000.000000 |     5 |
| SALESMAN  | 1400.000000 |     2 |
+-----------+-------------+-------+

select中的子查询(了解即可)

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

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

注意:对于select后面的子查询来说,这样的子查询只能返回一条结果,多于一条就报错!

12.union

查询工作岗位是MANGER和SALESMAN的员工

select ename,job from emp where job='MANAGER' or job='SALESMAN';
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 |
+--------+----------+
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 |
+--------+----------+

union的效率要高一些,对于表连接来说,每连接一次新表,则匹配的次数满足笛卡尔积,成倍的翻,但是union可以减少匹配的次数,在减少匹配次数的情况下,还可以完成两个结果集的拼接

union在进行结果集合并时要求两个结果集的列数相同

13.limit

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

百度默认:一页显示10条记录

分页的目的是为了提高用户的体验,因为一次全部都查出来,用户体验差

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

select ename,sal from emp order by sal desc limit 5; //取前5
select ename,sal from emp order by sal desc limit 0,5; //取前5 其中0为起始下标
+-------+---------+
| ename | sal     |
+-------+---------+
| KING  | 5000.00 |
| FORD  | 3000.00 |
| SCOTT | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+

mysql中limit在order by之后执行!!!

每页显示pageSize条记录

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

14.表

建表的语法格式:(建表属于DDL语句,DDL包括create drop alter)

create table 表名(

字段名1 数据类型,

字段名2 数据类型,

字段名3 数据类型

);

表名:建议以t_开头,可读性强,见名知意

字段名:见名知意

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

关于mysql中的常见数据类型:
varchar(最长255)

​ 可变长度的字符串

​ 比较智能,节省空间

​ 会根据实际的数据长度动态分配空间

​ 优点:节省空间

​ 缺点:需要动态分配空间,速度慢

char(最长255)

​ 定长字符串

​ 不管实际的数据长度是多少,分配固定长度的空间去存储数据

​ 使用不恰当时可能会导致空间的浪费

​ 优点:不需要动态分配空间,速度快

int(最长11)

​ 数字中的整数型,等同于java中的int

bigint

​ 数字中的长整型,等同于java中的long

float

​ 单精度浮点型数据

double

​ 双精度浮点型数据

date
段日期类型

datetime

​ 长日期类型

clob

​ 字符大对象

​ 最多可以存储4G的字符串

​ 可以存储一篇文章,存储一个说明

blob

​ 二进制大对象

​ 专门用来存储图片、声音、视频等流媒体数据

创建一个学生表

学号、姓名、年龄、性别、邮箱地址

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

删除学生表

drop table t_student;
drop table if exists t_student;

快速创建表

create table emp2 as select * from emp;
insert into dept_bak select * from dept; //很少用
15.insert

插入数据insert(DML)

语法格式:

​ insert into 表名(字段名1,字段名2,字段名3 …)values(值1,值2,值3);

insert into t_student(no,name,sex,age,email) values(1,'zhangsan','m',20,'123456789');

insert语句但凡执行成功必然会多一条记录

insert插入日期

数字格式化:format

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

select ename,format(sal,'$999.999') as sal from emp;
+--------+-------+
| ename  | sal   |
+--------+-------+
| SMITH  | 800   |
| ALLEN  | 1,600 |
| WARD   | 1,250 |
| JONES  | 2,975 |
| MARTIN | 1,250 |
| BLAKE  | 2,850 |
| CLARK  | 2,450 |
| SCOTT  | 3,000 |
| KING   | 5,000 |
| TURNER | 1,500 |
| ADAMS  | 1,100 |
| JAMES  | 950   |
| FORD   | 3,000 |
| MILLER | 1,300 |
+--------+-------+

str_to_date:将字符串varchar类型转换成date类型

date_format:将date类型转换成具有一定格式的varchar字符串类型

语法格式:

​ str_to_date(‘字符串日期’,‘日期格式’)

mysql的日期格式:

​ %Y 年

​ %m 月

​ %d 日

​ %h 时

​ %i 分

​ %s 秒

insert into t_user(id,name,birth) values(1,'zhangsan',str_to_date('01-10-1990','%d-%m-%Y'));

如果你提供的日期字符串是这个格式,str_to_date函数就不需要了!!!

‘%Y-%m-%d’

select id,name,date_format(birth,'%m/%d/%Y') as birth from t_user;

date和datetime两个类型的区别?

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

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

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

mysql中获取系统当前时间要使用now()函数,并且获取的时间有时分秒信息,是datetime类型的

insert插入多条数据

insert into t_user(id,name,birth,create_time) values
(1,'zs','1990-10-11',now()),
(2,'list','1981-10-11',now()),
(3,'wanglin','2001-06-06',now());
16.update

语法格式:

​ update 表名 set 字段名1=值1,字段名2=值2,字段名3=值3 where 条件;

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

17.delete

语法格式:

​ delete from 表名 where 条件;(属于DML语句)

注意:没有条件会删除整张表!!!

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

缺点是删除效率比较低

优点是支持回滚,后悔了可以再次恢复数据

truncate语句删除数据的原理

效率比较高,表被一次截断,物理删除

缺点是不支持回滚

优点是快速

truncate table dept_bak;(属于DDL操作)
18.约束

约束(constraint):

在创建表的时候可以给表中的字段加上一些约束来保证这个表中数据的完整性、有效性

非空约束:not null

唯一性约束:unique

​ 唯一性约束unique约束的字段不能重读,但可以为null

主键约束:primary key(简称PK)

外键约束:foreign key(简称FK)

检查约束:check(mysql不支持,oracle支持)

小插曲:xxxx.sql这种文件被称为sql脚本文件

sql脚本文件中编写了大量的sql语句

我们执行sql脚本文件的时候,该文件中所有的sql语句会全部执行

在mysql中可以使用’source 路径’ 的方式执行

新需求:name和email两个字段联合起来具有唯一性

drop table if exists t_vip;
create table t_vip(
	id int not null,  //not null只有列级约束,没有表级约束
	name varchar(255),  //约束直接添加到列后面的,叫做列级约束
	email varchar(255),
	unique(name,email)  //约束没有添加在列的后面,这种约束被称为表级约束
);
select * from t_vip;

在mysql中,如果一个字段同时被not null和unique约束的话,该字段自动变成主键字段(oracle中不同)

主键约束(primary key)

​ 主键约束、主键字段、主键值

主键值是每一行记录的唯一标识

主键值是每一行记录的身份证号

任何一张表都应该有主键,没有主键,表无效

主键的特征:not null + unique

单一主键和复合主键primary key(id,name)

一张表中主键只能添加一个

主键值建议使用int、bigint、char等类型

主键除了:单一主键和复合主键之外,还可以分为:

自然主键:主键值是一个自然数,和业务没关系

业务主键:主键值和业务紧密关联,例如拿银行账号做主键

在实际开发中自然主键比较多

在mysql中有一种机制可以帮我们自动维护一个主键

drop table if exists t_vip;
create table t_vip(
	id int primary key auto_increment,
	name varchar(255)
);
insert into t_vip(name) values ('zhangsan');

外键约束(foreign key)

​ 外键约束、外键字段、外键值

业务背景:请设计数据库表,来描述“班级和学生”的信息

先删子,后删父

先创父,后创子

drop table if exists t_student;
drop table if exists t_class;
create table t_class(
	classno int primary key,
	classname varchar(255)
);
create table t_student(
	no int primary key auto_increment,
	name varchar(255),
	cno int,
	foreign key(cno) reference t_class(classno)
);

注意:外键可以为null,子表中的外键引用的父表中的某个字段,被引用的这个字段不一定是主键,但至少具有唯一性

19.存储引擎

存储引擎是mysql中特有的一个术语

存储引擎是表存储/组织数据的方式

不同的存储引擎,表存储数据的方式不同

show create table t_vip;
CREATE TABLE `t_vip` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

在建表的时候可以在最后小括号的“ )”的右边使用:

​ ENGINE来指定存储引擎

​ CHARSET来指定这张表的字符编码方式

mysql默认的存储引擎是InnoDB,默认的字符编码方式是utf8

命令:show engines \G 查看mysql支持哪些存储引擎

MyISAM存储引擎

它管理的表具有以下特征:

​ 使用三个文件表示每个表:

​ 格式文件:存储表结构的定义(mytable.frm)

​ 数据文件:存储表行的内容(mytable.MYD)

​ 索引文件:存储表上索引(mytable.MYI)

​ 特点:可被转换为压缩、只读表来节省空间

InnoDB存储引擎

这是mysql默认的存储引擎,同时也是一个重量级的存储引擎

InnoDB存储引擎最主要的特点是:非常安全

它管理的表具有以下特征:

​ 每个InnoDB表在数据库目录中以.frm格式文件表示

​ InnoDB表空间tablespace被用于存储表的内容

​ 提供一组用来记录事务性活动的日志文件

​ 用COMMIT(提交)、SAVEPOINT及ROLLBACK(回滚)支持事务处理

​ 提供全ACID兼容

​ 在MYSQL服务器崩溃后自动回复

​ 多版本(MVCC)和行级锁定

​ 支持外键及引用的完整性,包括级联删除和更新

MEMORY存储引擎

使用MEMORY存储引擎的表,其数据都存储在内存中,且行的长度固定

这两个特点使得MEMORY存储引擎非常快

它管理的表具有以下特征:

​ 在数据库目录内,每个表均以.frm格式的文件表示

​ 表数据及索引被存储在内存中

​ 表级锁机制

​ 不能包含TEXT或BLOB字段

MEMORY存储引擎以前被称为HEAP引擎

​ 优点:查询效率最高

​ 缺点:不安全,关机之后数据消失

20.事务

一个事务(transaction)其实就是一个完整的业务逻辑

只有DML语句才会有事务这一说,其他语句和事务无关

insert delete update 数据安全第一位

如果所有的业务只需要一条DML语句就能完成,那么事务就没有必要存在了!

提交事务:commit

​ 清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中

​ 提交事务标志着事务的结束,并且是一种全部成功的结束

回滚事务:rollback

​ 将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件

​ 回滚事务标志着事务的结束,并且是一种全部失败的结束

mysql默认情况下是支持自动提交事务的,即每执行一条DML语句就会提交一次

mysql关闭自动提交机制:start transaction;

事务的四个特性

​ A:原子性 最小的工作单元

​ C:一致性 同时成功,同时失败

​ I:隔离性 事务之间具有一定的隔离

​ D:持久性 事务最终结束的一个保障

A教师和B教师中间有一道墙,这道墙可以很厚,也可以很薄,这就是事务的隔离级别

事务之间有4个隔离级别

​ 读未提交:read uncommited(最低的隔离级别)

​ 事务A可以读取到事务B未提交的数据

​ 读已提交:read commited

​ 事务A只能读取到事务B提交之后的数据

​ 可重复读:repeatable read (mysql中默认的事务隔离级别)

​ 事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的,即使事务B将数据已经修改并且提交了,事务A读取到的数据还是没有发生变化

​ 序列化:serializable(最高的隔离级别)

​ 效率最低,表示事务排队,不能并发

脏读不可重复读幻读
READ UNCOMMITTED(读未提交)
READ COMMITTED(读已提交)
REPEATABLE READ(可重复读)
SERIALIZABLE(串行化)

需要强调的是:MYSQL的可重复读解决了幻读的问题

21.索引

索引(index)是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制

一张表的一个字段可以添加一个索引,当然,多个字段联合起来也可以添加索引

索引相当于一本书的目录,是为了缩小扫描范围而存在的一种机制

mysql在查询方面主要就是两种方式:

​ 第一种:全表扫描

​ 第二种:根据索引检索

在mysql中索引是一个B-Tree数据结构

提醒:在任何数据库当中主键上都会自动添加索引对象

在mysql中,一个字段上如果有unique约束的话,也会自动创建索引对象

在任何数据库当中,任何一张表的任何一条记录在硬盘存储上都有一个硬盘的物理存储编号

在mysql中,索引是一个单独的对象,不同的存储引擎以不同的形式存在

​ 在MyISAM存储引擎中,索引存储在一个.MYI文件中

​ 在InnoDB存储引擎中,索引存储在一个逻辑名称叫做tablespace的当中

​ 在MEMORY存储引擎中,索引存储在内存当中

不管索引存储在哪里,索引在mysql中都是一个树的形式存在(自平衡二叉树:B-Tree)

什么条件下,需要考虑添加索引?

​ ①数据量庞大

​ ②该字段经常出现在where的后面

​ ③该字段很少的DML(insert delete update)操作

索引的创建

create index emp_ename_index on emp(ename);

给emp表的ename字段添加索引,起名:emp_ename_index

索引的删除

drop index emp_ename_index on emp;

将emp表上的emp_ename_index索引对象删除

查看一个SQL语句是否使用索引

explain select * from emp where ename = 'KING';

索引的失效

①模糊查询中以%开头时

即使添加了索引,也不会走索引

尽量避免模糊查询时以%开始

②使用or时也可能会失效

必须要求or两边的条件都要有索引才会走索引

③使用复合索引时,没有使用左侧的列查找,索引失效

create index emp_job_sal_index on emp(job,sal);
explain select * from emp where job = 'MANAGER';
explain select * from emp where sal = 800;

④在where中索引列参加了运算,索引失效

explain select * from emp where sal + 1 = 800;

⑤在where中索引列使用了函数,索引失效

explain select * from emp where lower(ename) = 'smith';

索引的分类

单一索引:一个字段上添加索引

复合索引:两个字段或者更多字段上添加索引

主键索引:主键上添加索引

唯一性索引:具有unique约束的字段上添加索引

注:唯一性比较弱的字段上添加索引的用处不大

22.视图

view:站在不同的角度去看待同一份数据

创建视图对象

create view emp_view as select * from emp;

删除视图对象

drop view emp_view;

我们可以面向视图对象进行增删改查,对视图对象的增删改查,会导致原表被操作!

假设有一条非常复杂的SQL语句,而这条SQL语句需要在不同的位置上反复使用,可以使用视图对象

可以大大简化开发利于维护

23.DBA命令

数据导出

​ 要在windows的dos命令窗口中

mysqldump bjpowernode>D:\bjpowernode.sql -uroot -p123456

​ 导出指定的表

mysqldump bjpowernode emp>D:\bjpowernode.sql -uroot -p123456

数据导入

​ 需要先登录到mysql数据库服务器上

​ 然后创建数据库:create database bjpowernode;

​ use bjpowernode;

create database bjpowernode;

use bjpowernode;

source D:\bjpowernode.sql
24.数据库设计三范式

学生编号 学生姓名 教师编号 教师姓名

1001 张三 001 王老师

1002 李四 002 赵老师

1003 王五 001 王老师

1001 张三 002 赵老师

第一范式:要求任何一张表必须有主键,每一个字段原子性不可再分

学生编号 + 教师编号(pk) 学生姓名 教师姓名

1001 001 张三 王老师

1002 002 李四 赵老师

1003 001 王五 王老师

1001 002 张三 赵老师

第二范式:建立在第一范式的基础上,要求所有非主键字段完全依赖主键,不能产生部分依赖

学生表

学生编号(pk) 学生姓名

1001 张三

1002 李四

1003 王五

教师表

教师编号(pk) 教师姓名

001 王老师

002 赵老师

学生教师关系表

id(pk) 学生编号(fk) 教师编号(fk)

1 1001 001

2 1002 002

3 1003 001

4 1001 002

多对多,三张表,关系表两个外键!

第三范式:建立在第二范式的基础上,要求所有非主键字段直接依赖主键,不能产生传递依赖

班级表

班级编号(pk) 班级名称

01 一年一班

02 一年二班

03 一年三班

学生表

学生编号(pk) 学生姓名 班级编号(fk)

1001 张三 01

1002 李四 02

1003 王五 03

1004 赵六 04

一对多,两张表,多的表加外键!

比较庞大的表可以拆分为两个表

一对一,外键唯一!

设计数据库表时按照以上范式进行,可以避免数据的冗余,空间的浪费

25.34道作业题

1)取得每个部门最高薪水的人员名称

select deptno,max(sal) as maxsal from emp group by deptno;

select
	e.ename,t.*
from
	emp e
join
	(select deptno,max(sal) as maxsal from emp group by deptno) t
on 
	e.sal = t.maxsal and e.deptno=t.deptno; 
+-------+--------+---------+
| ename | deptno | maxsal  |
+-------+--------+---------+
| BLAKE |     30 | 2850.00 |
| SCOTT |     20 | 3000.00 |
| KING  |     10 | 5000.00 |
| FORD  |     20 | 3000.00 |
+-------+--------+---------+

2)哪些人的薪水在部门的平均薪水之上

select deptno,avg(sal) as salavg from emp group by deptno;

select 
	e.ename,e.sal
from
	emp e
join
	(select deptno,avg(sal) as avgsal from emp group by deptno) t
on
	t.deptno = e.deptno
where
	e.sal > t.avgsal;
+-------+---------+
| ename | sal     |
+-------+---------+
| ALLEN | 1600.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| SCOTT | 3000.00 |
| KING  | 5000.00 |
| FORD  | 3000.00 |
+-------+---------+

3)①取得部门中(所有人的)平均的薪水等级

select 
	e.deptno,avg(s.grade)
from 
	emp e
join
	salgrade s
on
	e.sal between s.losal and s.hisal
group by
	deptno;

②取得部门中(所有人的)平均薪水的等级

select deptno,avg(sal) from emp group by deptno;

select 
	t.*,s.grade
from
	salgrade s
join
	(select deptno,avg(sal) as avgsal from emp group by deptno) t
on
	t.avgsal between s.losal and s.hisal;

4)不准用组函数(Max),取得最高薪水

select sal from emp order by sal desc limit 1;

select sal from emp where sal not in(
	select distinct a.sal from emp a join emp b on a.sal < b.sal
);

5)取得平均薪水最高的部门的部门编号

select 
	deptno,avg(sal) as avgsal 
from 
	emp 
group by 
	deptno 
order by 
	avgsal desc 
limit 1;

select 
	max(t.avgsal) 
from 
	(select avg(sal) as avgsal from emp group by deptno) t;

select
	distinct deptno
from
	emp
where
	deptno not in(
		select a.deptno 
		from (select deptno,avg(sal) as avgsal from emp group by deptno) a
		join (select deptno,avg(sal) as avgsal from emp group by deptno) b
		on a.avgsal < b.avgsal
	);

6)取得平均薪水最高的部门的部门名称

select 
	d.dname,e.deptno,avg(e.sal) as avgsal 
from 
	emp e
join
	dept d
on
	e.deptno = d.deptno
group by 
	e.deptno 
order by 
	avgsal desc 
limit 1;

7)求平均薪水的等级最低的部门的部门名称

select avg(sal) as avgsal from emp group by deptno order by avgsal limit 1;

select 
	grade 
from 
	salgrade 
where 
(select avg(sal) as avgsal from emp group by deptno order by avgsal limit 1) between losal and hisal;

select
	t.*,s.grade
from
	(select d.dname,avg(e.sal) as avgsal from emp e join dept d on e.deptno = d.deptno group by d.dname) t
join
	salgrade s
on
	t.avgsal between s.losal and s.hisal
where
	s.grade = (select 
				grade 
			from 
				salgrade 
			where 
				(select avg(sal) as avgsal from emp group by deptno order by avgsal limit 1) between losal and hisal);

8)取得比普通员工(员工代码没有在mgr字段上出现的)的最高薪水还要高的领导人姓名

select distinct mgr from emp;

select max(sal) from emp where 
	empno not in(select distinct mgr from emp where mgr is not null);
	
select ename,sal from emp where sal > (select max(sal) from emp where 
	empno not in(select distinct mgr from emp where mgr is not null));

9)取得薪水最高的前五名员工

select ename,sal from emp order by sal desc limit 5;

10)取得薪水最高的第六到第十名员工

select ename,sal from emp order by sal desc limit 5,5;

11)取得最后入职的5名员工

select ename,hiredate from emp order by hiredate desc limit 5;

12)取得每个薪水等级有多少员工

select 
	s.grade,count(*) 
from 
	emp e 
join 
	salgrade s 
on 
	e.sal between s.losal and s.hisal 
group by 
	s.grade;

13)面试题

有 3 个表 S(学生表),C(课程表),SC(学生选课表)

S(SNO,SNAME)代表(学号,姓名)

C(CNO,CNAME,CTEACHER)代表(课号,课名,教师)

SC(SNO,CNO,SCGRADE)代表(学号,课号,成绩)

问题:

1.找出没选过“黎明”老师的所有学生姓名

select 
	distinct sname 
from 
	s 
where
	sno not in 
		(select sno from sc where cno=
			(select cno from c where cteacher='liming')
		);

2.列出 2 门以上(含 2 门)不及格学生姓名及平均成绩

select 
	count(scgrade) as scsum,
	sno 
from 
	sc 
where 
	scgrade < 60 
group by 
	sno  
having 
	scsum >= 2;  
	
	
select 
	sname,avg(sc.scgrade) 
from 
	s 
join 
	(select count(scgrade) as scsum,sno from sc where scgrade < 60 group by sno having scsum >= 2) t
on
	t.sno =s.sno
join 
	sc
on 
	sc.sno  = t.sno;

3.既学过 1 号课程又学过 2 号课程的所有学生的姓名

select sno from sc where cno = '1';
select sno from sc where cno = '2';

select 
	s.name
from
	s
join
	(select sno from sc where cno = '1') a
on
	s.sno = a.sno
join
	(select sno from sc where cno = '2') b
on
	a.sno = b.sno;

14)列出所有员工及其领导的名字

select 
	a.ename as '员工',b.ename as '领导' 
from 
	emp a 
join 
	emp b 
on 
	a.mgr = b.empno;

15)列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称

select 
	a.empno,a.ename,d.dname
from 
	emp a 
join 
	emp b 
on 
	a.mgr = b.empno
join
	dept d
on 
	a.deptno = d.deptno
where
	a.hiredate < b.hiredate;

16)列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门

select 
	d.dname,e.* 
from 
	emp e 
right join 
	dept d 
on 
	d.deptno = e.deptno;

17)列出至少有5个员工的所有部门

select
	deptno
from 
	emp
group by 
	deptno
having
	count(*) >= 5;

18)列出薪金比"SMITH"多的所有员工信息

select * from emp where sal > (select sal from emp where ename = 'SMITH');

19)列出所有"CLERK"的姓名及其部门名称,部门的人数

select 
	e.ename,d.dname,t.部门人数
from 
	emp e 
join 
	dept d 
on 
	e.deptno = d.deptno 
join
	(select deptno,count(*) as '部门人数' from emp group by deptno) t
on
	e.deptno = t.deptno
where 
	e.job = 'CLERK';

20)列出最低薪金大于1500的各种工作及从事此工作的全部雇员人数

select
	job,count(*)
from 
	emp
group by
	job
having
	min(sal) > 1500;

21)列出在部门"SALES"工作的员工姓名,假定不知道销售部的部门编号

select 
	ename 
from 
	emp 
where 
	deptno = (select deptno from dept where dname = 'SALES');

22)列出薪金高于公司平均薪金的所有员工,上级领导,雇员的工资等级

select 
	e.ename,d.dname,l.ename,s.grade
from 
	emp e 
join
	dept d
on
	e.deptno = d.deptno
left join
	emp l
on
	e.mgr = l.empno
join
	salgrade s
on
	e.sal between s.losal and hisal
where
	e.sal > (select avg(sal) from emp);

23)列出与"SCOTT"从事相同工作的所有员工及部门名称

select 
	e.ename,e.job,d.dname
from
	emp e
join
	dept d
on
	e.deptno = d.deptno
where
	e.job = (select job from emp where ename = 'SCOTT')
and
	e.ename != 'SCOTT';

24)列出薪金等于部门30中员工的薪金的其他员工的姓名和薪金

select
	ename,sal
from 
	emp
where
	sal in (select distinct sal from emp where deptno = 30)
and
	deptno != 30;

25)列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金,部门名称

select
	e.ename,e.sal,d.dname
from 
	emp e
join
	dept d
on
	e.deptno = d.deptno
where
	e.sal > (select max(sal) from emp where deptno = 30);

26)列出在每个部门工作的员工数量,平均工资和平均服务期限

select
	d.deptno,
	count(e.ename) as ecount,
	ifnull(avg(e.sal),0) as avgsal,
	ifnull(avg(timestampdiff(YEAR,e.hiredate,now())),0) as avgservicetime
from
	emp e
right join
	dept d
on
	e.deptno = d.deptno
group by
	d.deptno;

27)列出所有员工的姓名,部门名称和工资

select
	e.ename,d.dname,e.sal
from 
	emp e
join
	dept d
on
	e.deptno = d.deptno;

28)列出所有部门的详细信息和人数

select
	d.deptno,d.dname,d.loc,count(e.ename)
from 
	emp e
right join
	dept d
on
	e.deptno = d.deptno
group by
	d.deptno,d.dname,d.loc;

29)列出各种工作的最低工资及从事此工作的雇员姓名

select
	e.ename,t.*
from
	emp e
join
	(select job,min(sal) as minsal from emp group by job) t
on
	e.job = t.job and e.sal = t.minsal;

30)列出各个部门的MANGER的最低薪金

select
	deptno,min(sal)
from
	emp
where
	job = 'MANAGER'
group by
	deptno;

31)列出所有员工的年工资,按年薪从低到高排序

select ename,(sal + ifnull(comm,0))*12 as yearsal from emp order by yearsal;

32)求出员工的领导的薪水超过3000的员工名称与领导姓名

select
	a.ename as '员工',b.ename as '领导'
from 
	emp a
join
	emp b
on
	a.mgr = b.empno
where
	b.sal > 3000;

33)求出部门名称中带’S’字符的部门员工的工资合计、部门人数

select
	d.deptno,count(e.ename),ifnull(sum(e.sal),0) as sumsal
from
	emp e
right join
	dept d
on
	e.deptno = d.deptno
where
	d.dname like '%S%'
group by
	d.deptno;

34)给任职日期超过30年的员工加薪10%

update emp set sal = sal * 1.1 where timestampdiff(YEAR,hiredate,now()) > 30;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zzzty_cs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值