什么是数据库?什么是数据库关系系统?什么是sql?
数据库:
DataBase,简称DB.按照一定格式存储数据的一些文件的组合
存储数据的仓库,实际上就是一堆文件.这些文件中存储了具有特定格式的数据
数据库管理系统:
DataBaseManagement,简称DBMS
数据库管理系统是专门进行管理数据库的,数据库管理系统可以对数据库当中的数据进行增删改查
MySql Oracle MS SqlServer
sql:结构化查询语言
sql是一套标准
三者之间的关系
DBMS--> 通过执行sql语句--> DB
2.安装mysql
1.安装mysql
2.需要进行mysql数据库实例配置
3.端口号:port是任何一个软件或应用都会有的,端口号是应用的唯一代表,具有唯一性
mysql数据库启动的时候这个服务默认端口是3306.
4.字符编码方式?
设置mysql数据库的字符集编码方式为utf8
一定要注意:先选中第三个按钮,然后在选择utf8字符集
5.选择环境变量怕配置path
6.mysql数据库超级管理员的用户名不能改,是root
你需要设置密码,一般为123456或者root
也可以激活root账户远程访问,
激活后可以在外地登录
3.mysql数据库的卸载
1.双击安装包卸载删除
2.删除目录:
2.1.把c:\programData下面的MySql目录删除
2.2.把c:\ProgramFiles(x86)下面的MySql目录删除
卸载结束
4.查看计算机上的服务
计算机->右键管理->服务与应用程序->服务->找mysql服务
mysql默认启动状态,只有启动了mysql才能用
也可右键mysql进行属性的设置,改变其手动还是自动等
5.windows操作系统使用命令启停mysql
net stop MySql 停mysql服务
net start MySql 启动服务器
6.登录MySql
命令终端:
mysql -uroot -proot
exit 退出mysql
7.mysql的常用命令
1.退出 exit
2.登录 mysql -uroot -proot
3.查看有全部数据库 show databases;
注意: 以分号结尾
4.怎么使用某个数据库?
use 数据库名字
就进入了这个数据库
5.创建数据库
craete database 数据库名字
6.show tables 查看数据库当中有哪些表
7.查看mysql的版本
select version();
8.查看当前使用的是哪个数据库?
select database();
mysql语句是不见分号不执行,分号表示结束!
8.表的理解
数据库当中最基本的单位是表. table
什么是表?为什么用表来存储数据呢?
数据库当中是以表格的形式存储数据的,任何一张表都有行和列
姓名 性别 年龄(字段)
-----------------
张三 男 13 -->行:数据/记录
李四 男 48
张乾康 男 45
袁梦梦 男 86
行(row):被称为数据/记录
列(column):被称为字段
每个字段都有字段名,数据类型,约束(唯一性)等属性
字段名:是一个普通的名字
数据类型:字符串,数字.日期
约束:很多,例唯一性约束,不能重复
9.sql分类
sql分为
DQL:
数据查询语言(凡是带有select)
select...
DML:
数据操作语言(凡是对表当中的数据进行增删改查的都是DML)
insert delete update
主要操作数据
DDL:
数据定义语言
凡是带有create(新增) drop(删除) alter(修改)
主要是操作表的结构 都是定义语言(DDL)
TCL:
是事务控制语言
包括事物提交:commit
事务回滚: rollback
DCL:
是数据控制语言
例授权grant...
撤销权限revoke...
10.导入表
1.进入数据库 use 数据库名
use bjpowernode;
2.将表结构导入:source 路径(不要有中文)
source D:\mysql_source\bjpowernode.sql;
3.导入后表的结构:
mysql> show tables;
+-----------------------+
| Tables_in_bjpowernode |
+-----------------------+
| dept 部门表 |
| emp 员工表 |
| salgrade 工资表 |
+-----------------------+
11.查看表中的数据
select * from 表名; //执行这个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 dept; 部门表
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
mysql> select * from salgrade; //工资表
+-------+-------+-------+
| GRADE | LOSAL | HISAL |
+-------+-------+-------+
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
+-------+-------+-------+
12.不看表中的数据,只看表中的结构=>desc
mysql> desc emp; //查看员工的结构 desc的缩写,describe,描述
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| EMPNO | int(4) | NO | PRI | NULL | |
| ENAME | varchar(10) | YES | | NULL | |
| JOB | varchar(9) | YES | | NULL | |
| MGR | int(4) | YES | | NULL | |
| HIREDATE | date | YES | | NULL | |
| SAL | double(7,2) | YES | | NULL | |
| COMM | double(7,2) | YES | | NULL | |
| DEPTNO | int(2) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
13.DQL简单查询语句
13.1.简单查询一个字段?
select 字段名 from 表名
select from 都是关键字
字段名 表名是标识符
强调:
对于sql语句是通用的,
所有的sql语句都是以";"结尾
另外sql语句不区分大小写,都可以
13.2 查询DNAME这个字段
mysql> select dname from dept;
+------------+
| dname |
+------------+
| ACCOUNTING |
| RESEARCH |
| SALES |
| OPERATIONS |
+------------+
13.3查询多个字段怎么办?
查询的多字段用逗号隔开
mysql> select dname,loc from dept;
+------------+----------+
| dname | loc |
+------------+----------+
| ACCOUNTING | NEW YORK |
| RESEARCH | DALLAS |
| SALES | CHICAGO |
| OPERATIONS | BOSTON |
+------------+----------+
13.4查询所有字段,可以使用*,也可以把字段都写上
select * from dept
13.5给查询的列起别名
mysql> select deptno,dname as deptName from dept;
+--------+------------+
| deptno | deptName |
+--------+------------+
| 10 | ACCOUNTING |
| 20 | RESEARCH |
| 30 | SALES |
| 40 | OPERATIONS |
+--------+------------+
注意:select语句是不会修改原表的
as 关键字也可以省略, 使用空格
mysql> select deptno,dname deptName from dept;
13.5.1 若你起的别名存在空格怎么办? 例:你起的为 dept Name
可以加引号(''或"")将其包裹住
mysql> select dname 'dept Name' from dept;
+------------+
| dept Name |
+------------+
| ACCOUNTING |
| RESEARCH |
| SALES |
| OPERATIONS |
+------------+
注意:在所有的数据库中,字符串统一使用单引号括起来
单引号是标准,双引号在oracle中不能使用
14.计算每个员工的年薪
年薪:sal*12
mysql> select ename,sal*12 as salYear from emp; //字段可以使用数学表达式
+--------+----------+
| ename | salYear |
+--------+----------+
| 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 |
+--------+----------+
15.条件查询
不是将所有的数据都查询出来,是查询出来符合条件的
语法格式:
select
字段一,字段二,...
from
表名
where
条件...
1.查询工资等于(=)800的员工姓名和编号
mysql> select empno,ename from emp where sal=800;
+-------+-------+
| empno | ename |
+-------+-------+
| 7369 | SMITH |
+-------+-------+
2.查询工资不等于(<>或!=)800的员工姓名和编号和薪资
mysql> select empno,ename,sal from emp where sal<>800;
+-------+--------+---------+
| empno | ename | sal |
+-------+--------+---------+
| 7499 | ALLEN | 1600.00 |
| 7521 | WARD | 1250.00 |
| 7566 | JONES | 2975.00 |
| 7654 | MARTIN | 1250.00 |
| 7698 | BLAKE | 2850.00 |
| 7782 | CLARK | 2450.00 |
| 7788 | SCOTT | 3000.00 |
| 7839 | KING | 5000.00 |
| 7844 | TURNER | 1500.00 |
| 7876 | ADAMS | 1100.00 |
| 7900 | JAMES | 950.00 |
| 7902 | FORD | 3000.00 |
| 7934 | MILLER | 1300.00 |
+-------+--------+---------+
3.查询薪资小于(<)2000的员工姓名和薪资
mysql> select ename,sal from emp where sal<2000;
+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| ALLEN | 1600.00 |
| WARD | 1250.00 |
| MARTIN | 1250.00 |
| TURNER | 1500.00 |
| ADAMS | 1100.00 |
| JAMES | 950.00 |
| MILLER | 1300.00 |
4.查询SMITH得薪资和编号
mysql> select empno,sal from emp where ename='SMITH';
+-------+--------+
| empno | sal |
+-------+--------+
| 7369 | 800.00 |
+-------+--------+
5.查询薪资在2450到3000的员工的信息?闭区间between..and...或 >=...and <=...
select ename,sal from emp where sal between 2450 and 3000;
也可用
select ename,sal from emp where sal >= 2450 and sal <= 3000;
+-------+---------+
| ename | sal |
+-------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
+-------+---------+
注意:使用between and时必须遵顼左小右大的方式
6.查询哪些员工的津贴为null?
mysql> select ename,sal from emp where comm is null; //用is来表示等于,不能用=号来表示,因为数据库中的null表示什么也没有,不能用=来划等号
+--------+---------+------+
| ename | sal | comm |
+--------+---------+------+
| SMITH | 800.00 | NULL |
| JONES | 2975.00 | NULL |
| BLAKE | 2850.00 | NULL |
| CLARK | 2450.00 | NULL |
| SCOTT | 3000.00 | NULL |
| KING | 5000.00 | NULL |
| ADAMS | 1100.00 | NULL |
| JAMES | 950.00 | NULL |
| FORD | 3000.00 | NULL |
| MILLER | 1300.00 | NULL |
+--------+---------+------+
7.查询哪些员工的津贴不为null?(is not)
mysql> select ename,sal,comm from emp where comm is not null;
+--------+---------+---------+
| ename | sal | comm |
+--------+---------+---------+
| ALLEN | 1600.00 | 300.00 |
| WARD | 1250.00 | 500.00 |
| MARTIN | 1250.00 | 1400.00 |
| TURNER | 1500.00 | 0.00 |
+--------+---------+---------+
8.找出工作岗位是manager,并且工资大于2500的员工信息?
mysql> select ename,sal,job from emp where job='manager' and sal>2500;
+-------+---------+---------+
| ename | sal | job |
+-------+---------+---------+
| JONES | 2975.00 | MANAGER |
| BLAKE | 2850.00 | MANAGER |
+-------+---------+---------+
9.查询工作岗位是manager和salesman的员工信息?
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 |
+--------+----------+
10.查询工资大于2500并且部门编号为10或者为20的员工信息?
mysql> select ename,sal,deptno from emp where sal>2500 and (deptno=10 or deptno=20); //加括号提升优先级
+-------+---------+--------+
| ename | sal | deptno |
+-------+---------+--------+
| JONES | 2975.00 | 20 |
| SCOTT | 3000.00 | 20 |
| KING | 5000.00 | 10 |
| FORD | 3000.00 | 20 |
+-------+---------+--------+
注意:and和or同时出现,and的优先级较高
11.查询工作岗位是manager和salesman的员工信息?(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 |
+--------+----------+
注意:in不是一个区间,in后面跟的是具体的值.
12.查询工作岗位不是manager和salesman的员工信息?(not in)
mysql> select ename,job from emp where job not in ('manager','salesman');
+--------+-----------+
| ename | job |
+--------+-----------+
| SMITH | CLERK |
| SCOTT | ANALYST |
| KING | PRESIDENT |
| ADAMS | CLERK |
| JAMES | CLERK |
| FORD | ANALYST |
| MILLER | CLERK |
+--------+-----------+
12.找出名字中含有o的?(like模糊下查询)
% 百分号表示任意多个字符
_ 下划线表示任意一个字符
mysql> select ename from emp where ename like '%o%';
+-------+
| ename |
+-------+
| JONES |
| SCOTT |
| FORD |
+-------+
12.2找出第二个字母是a的员工?
mysql> select ename from emp where ename like '_a%';
+--------+
| ename |
+--------+
| WARD |
| MARTIN |
| JAMES |
+--------+
12.3找出第三个字母是r的?
mysql> select ename ename_R from emp where ename like '__r%';
+---------+
| ename_R |
+---------+
| WARD |
| MARTIN |
| TURNER |
| FORD |
+---------+
12.4例如现在有个表t_student学生表的name字段
有zhangsan,lisi,wangwu,jack_son,...
找出名字中含有"_"的?
1.select name from t_student where name like '%_%'; //这样不行,因为下划线_ 具有特殊意义,这样就会把所有的全部找出来
2.select name from t_sudent where name like '%\_%'; //需要用\进行转义
16.查询所有员工工资
1.查询工资并升序排列
mysql> select ename,sal from emp order by sal; //使用order by进行升序排列
+--------+---------+
| 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 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
+--------+---------+
2.查询工资并降序排列
mysql> select ename,sal from emp order by sal desc; //通过在最后加上desc进行降序排列
+--------+---------+
| ename | sal |
+--------+---------+
| KING | 5000.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| MARTIN | 1250.00 |
| WARD | 1250.00 |
| ADAMS | 1100.00 |
| JAMES | 950.00 |
| SMITH | 800.00 |
+--------+---------+
3.指定升序的话,使用asc
select ename,sal from emp order by sal asc;
4.查询员工的名字和薪资,先按照薪资的升序排列,若薪资相同则按照名字的升序排列?
mysql> select ename,sal from emp order by sal asc,ename asc; //sal 在前,起主导作用,只有在sal相等的时候,才会考虑ename的asc的排序.
+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| JAMES | 950.00 |
| ADAMS | 1100.00 |
| MARTIN | 1250.00 |
| WARD | 1250.00 |
| MILLER | 1300.00 |
| TURNER | 1500.00 |
| ALLEN | 1600.00 |
| CLARK | 2450.00 |
| BLAKE | 2850.00 |
| JONES | 2975.00 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
+--------+---------+
也可以这样写,
mysql> select ename,sal from emp order by 2,1;
//2就表示根据你写的字段的位置,2就是sal,1就是ename,但不建议这样写,因为字段的顺序很容易发生改变
+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| JAMES | 950.00 |
| ADAMS | 1100.00 |
| MARTIN | 1250.00 |
| WARD | 1250.00 |
| MILLER | 1300.00 |
| TURNER | 1500.00 |
| ALLEN | 1600.00 |
| CLARK | 2450.00 |
| BLAKE | 2850.00 |
| JONES | 2975.00 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
+--------+---------+
17.综合案例
1.找出工资在1250到3000的员工信息,要求按照薪资降序排列
mysql> select ename,sal from emp where sal between 1250 and 3000 order by sal desc;
+--------+---------+
| ename | sal |
+--------+---------+
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| MARTIN | 1250.00 |
| WARD | 1250.00 |
+--------+---------+
注意:关键字顺序不能变
select
...
from
...
where
...
order by
....
以上语句的执行顺序必须掌握
第一步:from
第二部:where
第三步:select
第四步:排序(排序总是在最后的)
18.数据处理函数
数据处理函数又被称为单行处理函数
单行处理函数的特点:一个输入对呀一个输出
和单行处理函数对应的是:多行处理函数(多个输入对应一个输出)
18.1 常见的的单行处理函数有哪些?
lower 转换小写
mysql> select lower(ename) from emp;
+--------------+
| lower(ename) |
+--------------+
| smith |
| allen |
| ward |
| jones |
| martin |
| blake |
| clark |
| scott |
| king |
| turner |
| adams |
| james |
| ford |
| miller |
+--------------+
upper 转换大写
substr 取子串(substr(被截取的字符串,起始下标,截取的长度))
mysql> select substr(ename,1,3) from emp; //起始下标从一开始,没有0
+-------------------+
| substr(ename,1,3) |
+-------------------+
| SMI |
| ALL |
| WAR |
| JON |
| MAR |
| BLA |
| CLA |
| SCO |
| KIN |
| TUR |
| ADA |
| JAM |
| FOR |
| MIL |
+-------------------+
2.查询首字母为A的员工的名字(用substr函数)
mysql> select ename from emp where substr(ename,1,1)='A';
+-------+
| ename |
+-------+
| ALLEN |
| ADAMS |
+-------+
concat 字符串的拼接
1.将名字和薪资拼接到一块
mysql> select concat(ename,sal) from emp;
+-------------------+
| concat(ename,sal) |
+-------------------+
| SMITH800.00 |
| ALLEN1600.00 |
| WARD1250.00 |
| JONES2975.00 |
| MARTIN1250.00 |
| BLAKE2850.00 |
| CLARK2450.00 |
| SCOTT3000.00 |
| KING5000.00 |
| TURNER1500.00 |
| ADAMS1100.00 |
| JAMES950.00 |
| FORD3000.00 |
| MILLER1300.00 |
+-------------------+
2.将名字的首字母小写
mysql> select concat(lower(substr(ename,1,1)),substr(ename,2)) as result from emp;
+--------+
| result |
+--------+
| sMITH |
| aLLEN |
| wARD |
| jONES |
| mARTIN |
| bLAKE |
| cLARK |
| sCOTT |
| kING |
| tURNER |
| aDAMS |
| jAMES |
| fORD |
| mILLER |
+--------+
length 长度
获取名字的长度
mysql> select concat(length(ename),concat('-',ename)) as nameLength from emp;
+------------+
| nameLength |
+------------+
| 5-SMITH |
| 5-ALLEN |
| 4-WARD |
| 5-JONES |
| 6-MARTIN |
| 5-BLAKE |
| 5-CLARK |
| 5-SCOTT |
| 4-KING |
| 6-TURNER |
| 5-ADAMS |
| 5-JAMES |
| 4-FORD |
| 6-MILLER |
+------------+
trim 去空格
mysql> select * from emp where ename=trim(' SMITH'); //去除两端空格
+-------+-------+-------+------+------------+--------+------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+-------+-------+------+------------+--------+------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
+-------+-------+-------+------+------------+--------+------+--------+
str_to_date 将字符串转换为日期
date_format 格式化日期
format 设置千分位
round 四舍五入
mysql> select round(123.5674,1) as result from emp;//第二位代表保留小数点后几位.如果是-1,则是保留到十位,向前推.
+--------+
| result |
+--------+
| 123.6 |
| 123.6 |
| 123.6 |
| 123.6 |
| 123.6 |
| 123.6 |
| 123.6 |
| 123.6 |
| 123.6 |
| 123.6 |
| 123.6 |
| 123.6 |
| 123.6 |
| 123.6 |
+--------+
rand() 生成随机数
mysql> select round(rand()*100,0) as result from emp; //生成0-100以内的随机整数
+--------+
| result |
+--------+
| 27 |
| 91 |
| 74 |
| 99 |
| 70 |
| 56 |
| 67 |
| 70 |
| 49 |
| 35 |
| 28 |
| 35 |
| 89 |
| 41 |
+--------+
ifnull 可以将null转换为一个具体值
计算每个员工的年薪
年薪 = (月薪+补助)*12
mysql> select ename,(sal+comm)*12 as yearsal from emp;
+--------+----------+
| ename | yearsal |
+--------+----------+
| SMITH | NULL |
| ALLEN | 22800.00 |
| WARD | 21000.00 |
| JONES | NULL |
| MARTIN | 31800.00 |
| BLAKE | NULL |
| CLARK | NULL |
| SCOTT | NULL |
| KING | NULL |
| TURNER | 18000.00 |
| ADAMS | NULL |
| JAMES | NULL |
| FORD | NULL |
| MILLER | NULL |
+--------+----------+
注意:null只要参与运算,最终结果一定是null,为了避免这个现象的出现,使用 ifnull函数
ifnull(数据,被当作那个值?) //如果数据为null时,将null当作哪个值
mysql> select ename,round((sal+ifnull(comm,0))*12,0) as yearsal from emp;
//如果comm为null则将其看为0对待运算
+--------+---------+
| ename | yearsal |
+--------+---------+
| SMITH | 9600 |
| ALLEN | 22800 |
| WARD | 21000 |
| JONES | 35700 |
| MARTIN | 31800 |
| BLAKE | 34200 |
| CLARK | 29400 |
| SCOTT | 36000 |
| KING | 60000 |
| TURNER | 18000 |
| ADAMS | 13200 |
| JAMES | 11400 |
| FORD | 36000 |
| MILLER | 15600 |
case..when..then..when..then..else..end
跟if else if else差不多
1.当员工的工作岗位是manager时,工资上调10%,当是salesman时,工资上调50%,其它正常
mysql> select ename,job,sal oldsal,(case job when 'manager' then sal*1.1 when 'salesman' then sal*1.5 else sal end) as newsal from emp;//打印出oldsal,和计算出newsal
+--------+-----------+---------+---------+
| 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 |
+--------+-----------+---------+---------+
19.当查找字面量时
mysql> select 'abc' ename from emp; //查找abc字面量时,它会查找14个abc
+-------+
| ename |
+-------+
| abc |
| abc |
| abc |
| abc |
| abc |
| abc |
| abc |
| abc |
| abc |
| abc |
| abc |
| abc |
| abc |
| abc |
+-------+
2.当查找1000这个字面量时
mysql> select 1000 as num from emp;
+------+
| num |
+------+
| 1000 |
| 1000 |
| 1000 |
| 1000 |
| 1000 |
| 1000 |
| 1000 |
| 1000 |
| 1000 |
| 1000 |
| 1000 |
| 1000 |
| 1000 |
| 1000 |
+------+
注意:select后面可以跟某个表的字段名
20.分组函数(多行处理函数)
多行处理函数的特点:输入多行,最终输出一行
1.count 计数
2.sum 求和
3.avg 平均值
4.max 最大值
5.min 最小值
分组函数在使用时必须先进行分组,然后才能用,
如果你没有进行分组,整张表默认为一组
注意:
1.分组函数自动忽略null,不需要提前对null进行处理.
2.分组函数中count(*)和count(具体字段)有什么区别?
count(具体字段),表示统计该字段下所有不为null的总数
count(*)统计表当中的总行数
3.分组函数不能够直接使用在where子句中。
说完分组查询(group by)之后就明白了.
4.分组函数可以一起用
mysql> select max(sal),min(sal),avg(sal),sum(sal) from emp;
+----------+----------+-------------+----------+
| max(sal) | min(sal) | avg(sal) | sum(sal) |
+----------+----------+-------------+----------+
| 5000.00 | 800.00 | 2073.214286 | 29025.00 |
+----------+----------+-------------+----------+
21.分组查询(重要)
1.什么是分组查询?
在实际应用中,可能有这样的需求,需要先进行分组,然后对每一组的数据进行操作,这个时候我们需要使用分组查询,怎么进行分组查询呢?
select
....
from
....
group by
....
21.1将之前的关键字全部组合在一起,看他们的执行顺序?
select
...
where
...
group by
...
order by
...
以上关键字的顺序不能颠倒,需要记忆!!
执行顺序是什么?
1.from
2.where
3.group by
4.select
5.order by
为什么分组函数不能直接使用在where后面?
select ename,sal from emp where sal>min(sal)?报错
因为分组函数使用的时候,必须先进行分组之后才能使用
where(第二个执行)执行的时候,还没有进行分组(第三个执行),所以where后面不能出现分组函数
21.2找出每个工作岗位的工资和?
mysql>
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 ename,job,sum(sal)
from emp
group by job;
注意:
在一条select语句当中,如果有group by语句的话,
select后面只能跟: 参加分组的字段,以及分组函数,
其它一律不能跟
21.3找出每个部门的最高薪资?
mysql> select deptno,max(sal) from emp group by deptno;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
| 10 | 5000.00 |
| 20 | 3000.00 |
| 30 | 2850.00 |
+--------+----------+
21.4找出每个部门,不同工作岗位的最高薪资?
两个分组条件,1.部门分组 2.工作岗位再进行分组,最后输出全部符合条件的
mysql>
select max(sal),job,deptno
from emp
group by deptno,job;
+----------+-----------+--------+
| max(sal) | job | deptno |
+----------+-----------+--------+
| 1300.00 | CLERK | 10 |
| 2450.00 | MANAGER | 10 |
| 5000.00 | PRESIDENT | 10 |
| 3000.00 | ANALYST | 20 |
| 1100.00 | CLERK | 20 |
| 2975.00 | MANAGER | 20 |
| 950.00 | CLERK | 30 |
| 2850.00 | MANAGER | 30 |
| 1600.00 | SALESMAN | 30 |
+----------+-----------+--------+
21.5 找出每个部门的最高薪资,要求显示最高工资大于三千的?(使用having可以分完组后进行过滤),having不能单独使用,必须结合group by,并且having不能代替where
mysql> select max(sal),deptno from emp group by deptno having max(sal)>3000;
+----------+--------+
| max(sal) | deptno |
+----------+--------+
| 5000.00 | 10 |
+----------+--------+
第二种解法:
mysql> select max(sal),deptno from emp where sal>3000 group by deptno;
+----------+--------+
| max(sal) | deptno |
+----------+--------+
| 5000.00 | 10 |
+----------+--------+
注意:where和having,能用where先用where.
21.6找出每个人部门的平均工资,并且平均薪资高于2500的?
mysql> select avg(sal),deptno from emp group by deptno having avg(sal)>2500;
+-------------+--------+
| avg(sal) | deptno |
+-------------+--------+
| 2916.666667 | 10 |
+-------------+--------+
22.大总结(单表)
select
...
from
...
where
...
geoup by
...
having
...
order by
...
以上关键字只能按照上方的顺序来,不能颠倒
执行顺序为:
1.from
2.where
3.group by
4.having
5.select
6.order by
从某张表中查询数
先经过where条件筛选出有价值的数据,
对这些数据再进行分组,
分组之后可以用having进行继续筛选
最后排序输出
22.1 找出每个岗位平均薪资,要求显示平均薪资大于1500的,除manager之外,要求平均薪资降序排列.
mysql> select avg(sal),job from emp where job != 'manager' group by job having avg(sal)>1500 order by avg(sal) desc;
条件是job不是manager的,分组为job,子条件为平均工资大于1500的,排序为平均工资降序.
+-------------+-----------+
| avg(sal) | job |
+-------------+-----------+
| 5000.000000 | PRESIDENT |
| 3000.000000 | ANALYST |
+-------------+-----------+
23.去除重复记录
将查询结果去重,使用关键字distinct.不会对原表产生影响,只能出现所有字段的最前方.
mysql> select count(distinct(job)) as numDis from emp;
+--------+
| numDis |
+--------+
| 5 |
+--------+
24.连接查询(超级重点)
从一张表中单独查询,称为单表查询
emp和dept表联合起来查询数据,从emp标志取员工名字,从部门表中取部门名字
这种跨表查询,多张表联合起来查询数据,被称为连接查询.
1.连接查询的分类?
根据语法的年代分类:
sql92: 1992年出现的语法
sql99:1999年出现的语法
重点学习99.
表连接方式分类?
内连接:
等值连接
非等值连接
自链接
外连接:
左外连接(左连接)
右外连接(右连接)
全连接
24.2当两张表进行连接查询时,没有任何条件的限制,会发生什么样的现象?
会发生笛卡尔积现象,没有任何限制时,查询的数量是两张表数量的乘积.
1.怎么避免笛卡尔积现象?
连接时加条件,满足条件的记录筛选出来.
24.2.1查询每个员工做所在部门的名称?
mysql> select ename,dname from emp,dept where emp.deptno = dept.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 |
+--------+------------+
注意:匹配的结果少了,但匹配的次数不会减少.
并且效率不高,因为ename会去dept找,dname会区emp找.所以为了提高效率,可以将其查找的加上表名:
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 |
+--------+------------+
25内连接之等值连接
1.找出员工的部门,输出员工名字和部门名字
select
-> e.ename,d.dname
-> from
-> emp e
->(inner可省略) join
-> dept d
-> on
-> e.deptno=d.deptno; //等值连接,条件是等量关系
//join on sql99方法
sql92缺点:结构不清晰,将表的连接和后期进一步筛选的条件,都放到了where后面.
sql99的优点,表连接条件是独立的,连接之后,如果还需要进一步筛选,再往后添加where即可
+--------+------------+
| 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 |
+--------+------------+
注意;sql99的语法
select
...
from
a
join
b
on
a和b的连接条件
where
筛选条件
26.内连接之非等值连接
1.找出每个员工的薪资等级,要求显示员工名 薪资 薪资等级?
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 |
+--------+---------+-------+
27.内连接之自连接
查询员工的上级领导,要求显示员工名个对应的领导名?
mysql> select e.ename,e2.ename Pname from emp e
-> join emp e2
-> on
-> e.mgr = e2.empno; //员工的领导编号等于领导的员工编号
+--------+-------+
| ename | Pname |
+--------+-------+
| 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 |
+--------+-------+
以上就是内连接的自连接,技巧:一张表看成两张表
28.外连接
1.找出员工所在部门,并且显示员工姓名和(全部)部门
mysql> select e.ename,d.dname from emp e
-> right (outer可省略) 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 |
+--------+------------+
注意:内连接与外连接的区别就是有没有right与left关键字,有就是外连接.
外连接的查询结果条数一定是>= 内连接的查询结果条数
mysql> select e.ename '员工名',e2.ename '领导名'
from emp as e
left join
emp e2
on
e.mgr =e2.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 |
+--------+--------+
29.三张表,四张表的连接
语法:
select
...
from
a
join
b
on
a和b的连接条件
join
c
on
a和c的连接条件
join
d
on
a和d的连接条件
案例:(三张表进行连接)
找出每个员工的部门名称以及工资等级,要求显示员工名\部门名\薪资\薪资等级?
mysql> select e.ename,e.sal,d.dname,s.grade from emp as e
-> join dept as d
-> on
-> e.deptno = d.deptno
-> join salgrade as 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 |
+--------+---------+------------+-------+
2.案例:
找出每个员工的部门名称以及工资等级,还有上级领导,要求显示员工名\领导名\部门名\薪资\薪资等级?
select
e.ename,e2.ename Pname,e.sal,d.dname,s.grade
from emp e
left join emp e2
on
e.mgr = e2.empno
join dept d
on
e.deptno = d.deptno
join salgrade s
on
e.sal between s.losal and s.hisal;
+--------+-------+---------+------------+-------+
| ename | Pname | sal | dname | grade |
+--------+-------+---------+------------+-------+
| SMITH | FORD | 800.00 | RESEARCH | 1 |
| ALLEN | BLAKE | 1600.00 | SALES | 3 |
| WARD | BLAKE | 1250.00 | SALES | 2 |
| JONES | KING | 2975.00 | RESEARCH | 4 |
| MARTIN | BLAKE | 1250.00 | SALES | 2 |
| BLAKE | KING | 2850.00 | SALES | 4 |
| CLARK | KING | 2450.00 | ACCOUNTING | 4 |
| SCOTT | JONES | 3000.00 | RESEARCH | 4 |
| KING | NULL | 5000.00 | ACCOUNTING | 5 |
| TURNER | BLAKE | 1500.00 | SALES | 3 |
| ADAMS | SCOTT | 1100.00 | RESEARCH | 1 |
| JAMES | BLAKE | 950.00 | SALES | 1 |
| FORD | JONES | 3000.00 | RESEARCH | 4 |
| MILLER | CLARK | 1300.00 | ACCOUNTING | 2 |
+--------+-------+---------+------------+-------+
30.子查询?
30.1什么是子查询?
select语句中嵌套select语句,被嵌套的select语句被称为子查询.
30.2子查询都可以出现在哪里呢?
select
..(select).
from
...(select)
where
..(select).
30.3 where子句中出现子查询
案例:
找出比最低工资高的员工的姓名,薪资
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 |
+--------+---------+
30.4.from中的子查询,可以将子查询的查询结果当作一个临时表(技巧).
案例:
找出每个岗位的平均工资的薪资等级.
1.select avg(sal),job from emp group by job;
select
s.grade,t.*
from
salgrade s
join
(select avg(sal) as avgSal,job from emp group by job) as t
on
avgSal between s.losal and s.hisal
order by
s.grade asc;
+-------+-------------+-----------+
| grade | avgSal | job |
+-------+-------------+-----------+
| 1 | 1037.500000 | CLERK |
| 2 | 1400.000000 | SALESMAN |
| 4 | 3000.000000 | ANALYST |
| 4 | 2758.333333 | MANAGER |
| 5 | 5000.000000 | PRESIDENT |
+-------+-------------+-----------+
30.5.select后面出现的子查询(这个内容不需要掌握,了解即可!!!)
案例:
找出每个员工的部门名称,要求显示员工名,部门名?
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 |
+--------+------------+
第二种解决办法.select子查询
mysql>
select e.ename,
(select d.dname,deptno from dept d where e.deptno=d.deptno) 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 |
+--------+------------+
31.union合并查询结果集
查询工作岗位是manager和salesman的员工?
mysql> select ename,job from emp where job='manager'
-> union
-> select ename,job from emp where job='salesman';
//使用union进行查询结果的合并,(union的效率的高一些),union把乘法变成了加法.
注意:union在进行结果集合并的时候,查询的结果列数得相同,在mysql中类型不一定一样,但在oracle中就会报错,oracle必须使其列数和类型都相同才能合并
+--------+----------+
| ename | job |
+--------+----------+
| JONES | MANAGER |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| MARTIN | SALESMAN |
| TURNER | SALESMAN |
+--------+----------+
32.limit(很重要)
limit的作用:将查询结果集的一部分取出来,通常使用在分页的查询当中.
limit的用法? [startIndex:起始下标],length:数量
1.按照薪资降序,取出排名在前五名的员工?
select ename,sal
from emp
order by sal desc
limit 0,5;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
注意:在mysql中limit是在order by之后执行
2.取出工资排名在3-5名的员工?
select ename,sal from emp
order by sal desc
limit 2,3; //3-5名,一共是3,4,5,三名,从三开始,也就是下标2,
+-------+---------+
| ename | sal |
+-------+---------+
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
3.去除工资排名在5-9名的数据?
select ename,sal from emp order by sal desc limit 4,5;
+--------+---------+
| ename | sal |
+--------+---------+
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
+--------+---------+
33分页
每页显示三条记录
第一页: limit 0,3 [0,1,2]
第二页:limit 3,3 [3,4,5]
第三页:limit 6,3 [6,7,8]
每页显示pageSize条数据
第pageNo页: limt (pageNo-1)*pageSize,pageSize
34.关于DQL的大总结
select
...
from
...
where
...
group by
...
having
...
order by
...
limit
...
执行顺序:
1.from
2.where
3.group by
4.having
5.select
6.order by
7.limit
34个作业题:
1.创建表DDL语句(create,drop alter)
1.create table 表名(
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型
);
表名建议以t_ 或者tbl_开始,可读性强
2.关于mysql中的数据类型?
varchar(255) =>可变长度的字符串,比较智能,节省空间,会根据实际的数据成都动态的娥分配空间.
优点:节省空间
缺点:动态的分配空间,速度慢
char(255) =>固定长度字符串,不管实际的数据长度是多少,分配固定的空间去存储数据.
优点:效率高
缺点:可能会导致空间的浪费.
性别采用 char(..)
int(11) =>整数型
bigint =>长整型 java的long
float => 单精度浮点型数据
double =>双精度浮点型数据
date => 短日期类型
datetmie=> 长日期类型
clob =>
字符大对象
最多可以存储4G的字符串
比如:才能出一篇文章,存储一篇说明
超过255的字符的都要采用clob字符大对象来存储
blob =>
二进制大对象
binary large Object
著名来存储图片,声音,视频等流媒体数据
往BLOB字段插入数据的时候,得用IO流才行
1.2t_move 电影表(专门存储电影信息的)
编号 名字 描述
no(bigint) name(varchar) description(clob)
10000 长津湖 这是一个战争类型的大型电影,非常nice
上映日期 时长 海报 类型
playtime(date) time(double) image(blob) type(char)
2021-10-1 2.2 ... '1'
1.3创建学生表
学号,姓名,年龄,性别邮箱地址
create table t_student(
no int,
name varchar(255),
age int(3),
gender char(1),
email varchar(255)
);
删除表:
drop table t_student; //当这张表不存在的时候会报错
drop table if exists t_student; //如果存在删除!
1.4插入数据==(insert)(DML)==
insert into 表名(`字段`1,字段2,字段3) values(值1,值2,值3);
字段和值一一对应,数量要对应,数据类型也要对应.
insert into t_student(no,name,age,gender,email) values(1,'zhangqiankang',20,'m','2315119543@qq.com');
insert into t_student(email,no,name,age,gender) values('577934719@qq.com',2,'ymm',20,'f');
insert into t_student(no) values(3);
insert into t_student(name) values('ymmzqk')
注意:insert 只要执行成功了,就会增加一条记录,
没有给其它字段指定值的话,默认值是NULL.
删除表再创建.
drop tables if exists t_student;
create table t_student(
no int,
name varchar(32),
age int(3),
gender char(1) default 'm', //默认值
email varchar(255)
);
insert into t_student(no) values(1);
1.insert语句中的字段名可以省略嘛?
insert table t_student values(2); //报错
注意:前面的字段名省略的话,相当于都写上了,所以值也都要写上!
insert into t_student values(2,'lisi',20,'f','123456@qq.com'); //字段名都不写,所以相当于全都写上.
1.5insert插入日期
日期函数:
str_to_date:将字符串varchar转换为date类型
date_format:将date类型转换为具有一定格式的varchar字符串类型
create table t_user(
id int,
name varchar(32),
birth date,
create_time bigint
);
注意:数据库中的有一条命名规范:
所有的娥标识符都是全部小写,单词和单词之间使用下划线进行衔接.
insert into t_user(id,name,birth,create_time) values(1,'lisi',str_to_date('1999-03-10','%Y-%m-%d'),20220322);
mysql的日期格式:
%Y 年
%m 月
%d 日
%h 时
%i 分
%s 秒
str_to_date函数可以把字符串varchar转换成date类型数据,通常使用在insert方面,因为插入的时候需要将一个日期格式的数据,需要通过该函数将字符串转化为date
好消息,如果你提供的日期字符串是固定的这个格式,str_to_date就不需要了!!
%Y-%m-%d z这个格式
insert into t_user(id,name,birth,create_time) values(2,'zhangsan','2001-05-22',20220322);
2.在查询日期时,能以特定的格式呈现嘛?
可以用date_format来进行格式化
select name,date_format(birth,'%d/%m/%Y') datebirth from t_user; //通过使用date_format来转换为字符串.
date_format怎么用?
date_format(日期类型数据,'日期格式')
这个函数通常使用在查询方面.设置展示的日期格式.
若日期格式不适应date_format转换可以输出嘛?
select name,birth from t_user;
+----------+------------+
| name | birth |
+----------+------------+
| lisi | 1999-03-10 |
| zhangsan | 2001-05-22 |
+----------+------------+
这里默认是进行了日期格式转换.自动将date类型转换成了varchar类型.
总结:str_to_date可以将字符串转换为日期类型,date_format可以将日期格式转换为字符串
1.6date和datetime区别?
date是短日期,只包括年月日
datetime是长日期,包括年月日时分秒的娥信息
drop table if exists t_user;
create table t_user(
id int,
name varchar(32),
birth date,
create_time datetime
);
注意:mysql 短日期默认格式:%Y-%m-%d.
长日期格式: %Y-%m-%d %h:%i:%s
insert into t_user(id,name,birth,create_time) values(1,'lisi','2002-02-22','2022-03-22 22:16:45');
在mysql当中怎么获取当前时间呢?
用now() 方法
insert into t_user(id,name,birth,create_time) values(2,'caobie','2001-05-12',now());
1.7改 update(DML)
update 表名 set 字段1=值1,字段2=值2 where 条件;
注意: 没有条件限制会导致所有数据全部更新.
update t_user set name= 'zhengtianyi',birth='2000-02-29',create_time = now() where id =1;
1.8 delete删除数据(DML)
delete from 表名 where 条件;
若无条件,则整张表都会被删除!!!
delete from t_user where id = 2;
34道作业题
1.取得每个部门最高薪水的人员名称
1.1select deptno,max(sal) as maxsal from emp group by deptno;
+--------+---------+
| deptno | maxsal |
+--------+---------+
| 10 | 5000.00 |
| 20 | 3000.00 |
| 30 | 2850.00 |
+--------+---------+
//取得每个部门最高的是多少.
1.2.select e.ename,t.* from emp e join (select deptno,max(sal) as maxsal from emp group by deptno) t
on e.deptno = t.deptno and e.sal = t.maxsal;
2.哪些人的薪水在部门的平均薪水之上?
2.1 select avg(sal) from emp group by deptno;
+-------------+
| avg(sal) |
+-------------+
| 2916.666667 |
| 2175.000000 |
| 1566.666667 |
+-------------+
2.2 select e.ename,e.sal from emp e join (select deptno,avg(sal) as avgsal from emp group by deptno) t on
e.deptno = t.deptno and 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 grade,sal,deptno from emp join salgrade s on
sal between s.losal and s.hisal; //先找出每个人的薪资等级
+-------+---------+--------+
| GRADE | sal | deptno |
+-------+---------+--------+
| 1 | 800.00 | 20 |
| 3 | 1600.00 | 30 |
| 2 | 1250.00 | 30 |
| 4 | 2975.00 | 20 |
| 2 | 1250.00 | 30 |
| 4 | 2850.00 | 30 |
| 4 | 2450.00 | 10 |
| 4 | 3000.00 | 20 |
| 5 | 5000.00 | 10 |
| 3 | 1500.00 | 30 |
| 1 | 1100.00 | 20 |
| 1 | 950.00 | 30 |
| 4 | 3000.00 | 20 |
| 2 | 1300.00 | 10 |
+-------+---------+--------+
select avg(t.grade),deptno from (select grade,sal,deptno from emp join salgrade s on
sal between s.losal and s.hisal) t group by t.deptno;
//然后再根据部门求得薪资等级的平均值
+--------------+--------+
| avg(t.grade) | deptno |
+--------------+--------+
| 3.6667 | 10 |
| 2.8000 | 20 |
| 2.5000 | 30 |
+--------------+--------+
4、不准用组函数(Max),取得最高薪水(给出两种解决方案)
第一种:select sal from emp order by sal desc limit 1;//降序,取1.
+---------+
| sal |
+---------+
| 5000.00 |
+---------+
第二种:表连接
select sal from emp where sal not in (select distinct a.sal from emp a join emp b on
a.sal<b.sal
);//查询sal,并且条件是sal不在子查询内,而子查询是,令两个emp表(a,b)连接,并且条件为a的sal小于b的sal的 a的sal,并去重,所以只有最大的不会小于自己表中的sal.
5、取得平均薪水最高的部门的部门编号(至少给出两种解决方案)
select avg(sal) as avgsal,deptno from emp group by deptno;
select max(t.avgsal) Tsal,d.deptno from (select avg(sal) as avgsal,deptno from emp group by deptno) t join dept d on
d.deptno = t.deptno;
+-------------+--------+
| Tsal | deptno |
+-------------+--------+
| 2916.666667 | 10 |
+-------------+--------+
第二种:将查询出来部门的平均工资,进行降序排序,然后取出第一个就是最高的那个,然后跟部门表进行连接,取出和部门编号相同的即可
select avg(sal) as avgsal,deptno from emp group by deptno order by avgsal desc limit 1;
select t.avgsal Tsal_tow,d.deptno from (select avg(sal) as avgsal,deptno from emp group by deptno order by avgsal desc limit 1) t join dept d on
d.deptno = t.deptno;
+-------------+--------+
| Tsal_tow | deptno |
+-------------+--------+
| 2916.666667 | 10 |
+-------------+--------+
6.取得平均薪水最高的部门的部门名称
select avg(sal) avgsal_T from emp group by deptno order by avgsal_T desc limit 1;
select
d.dname
from
dept d
join
(select avg(sal) as avgsal,deptno from emp group by deptno order by avgsal desc limit 1) as t
on
d.deptno = t.deptno;
// 首先查询出来平均薪资最高的部门编号,然后再再进行表连接筛选出编号相同的部门名字。
+------------+
| dname |
+------------+
| ACCOUNTING |
+------------+
7.求平均薪水的等级最低的部门的部门名称
select avg(sal) avgsal,deptno from emp group by deptno order by avgsal asc limit 1; //先查出最低的平均工资编号
select
d.dname
from
dept d
join
(select avg(sal) as avgsal,deptno from emp group by deptno order by avgsal asc limit 1) as t
on
d.deptno = t.deptno;//然后再根据编号查出部门
+-------+
| dname |
+-------+
| SALES |
+-------+
8.取得比普通员工(员工代码没有在mgr字段上出现的)的最高薪水还要高的领导人姓名
1.员工代码没有在mgr上面也就是 not in,然后再取出这其中最高的工资为多少:
1.取出mgr不为null的.
select mgr from emp where mgr is not null;
select max(sal) from emp where empno not in (select mgr from emp where mgr is not null); //找出工人的最高薪资
select ename,sal from emp,(select max(sal) maxsal from emp where empno not in (select mgr from emp where mgr is not null)) t where sal>t.maxsal; //然后找出领导人姓名,条件是工资大于那个工人最高工资.
+-------+---------+
| ename | sal |
+-------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
| FORD | 3000.00 |
+-------+---------+
9.取得薪水最高的前五名员工
select ename,sal from emp order by sal desc limit 0,5;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
10、取得薪水最高的第六到第十名员工
select ename,sal from emp order by sal desc limit 5,5;
+--------+---------+
| ename | sal |
+--------+---------+
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| MARTIN | 1250.00 |
+--------+---------+
//直接limit 5,5 从五开始,数量为5
11、取得最后入职的5名员工
select ename,hiredate,date_format(hiredate,'%Y%m%d') dateformathire from emp order by date_format(hiredate,'%Y%m%d') desc limit 5; //先将日期格式化,然后再将其排序降序输出,条数为5个
+--------+------------+--------------------------------+
| ename | hiredate | date_format(hiredate,'%Y%m%d') |
+--------+------------+--------------------------------+
| ADAMS | 1987-05-23 | 19870523 |
| SCOTT | 1987-04-19 | 19870419 |
| MILLER | 1982-01-23 | 19820123 |
| FORD | 1981-12-03 | 19811203 |
| JAMES | 1981-12-03 | 19811203 |
+--------+------------+--------------------------------+
12、取得每个薪水等级有多少员工
select s.grade,count(s.grade) Gradenum from emp e join salgrade s on
e.sal between s.losal and s.hisal group by s.grade;
+-------+----------+
| grade | Gradenum |
+-------+----------+
| 1 | 3 |
| 2 | 3 |
| 3 | 2 |
| 4 | 5 |
| 5 | 1 |
+-------+----------+
13.面试题(学生,课程,学生选课)
//课程表
+------+----------+----------+
| CNO | CNAME | CTEACHER |
+------+----------+----------+
| 1 | yuwen | zhang |
| 2 | zhengzhi | wang |
| 3 | yingyu | li |
| 4 | shuxue | zhao |
| 5 | wuli | liming |
+------+----------+----------+
//学生表
+------+----------+
| SNO | SNAME |
+------+----------+
| 1 | student1 |
| 2 | student2 |
| 3 | student3 |
| 4 | student4 |
+------+----------+
//学生选课表
+------+------+---------+
| SNO | CNO | SCGRADE |
+------+------+---------+
| 2 | 1 | 60 |
| 2 | 3 | 60 |
| 2 | 4 | 60 |
| 2 | 5 | 40 |
| 3 | 3 | 80 |
| 1 | 1 | 40 |
| 1 | 2 | 30 |
| 1 | 4 | 80 |
| 1 | 5 | 60 |
+------+------+---------+
1.找出没选过“黎明”老师的所有学生姓名
select distinct sname from s where
sno not in (select sno from sc where cno=(select cno from c where cteacher='liming'));
+----------+
| sname |
+----------+
| student3 |
| student4 |
+----------+
/先通过liming找出对应的课程号,然后通过课程号找出选这个课程号的学号,然后再输出不是这些学号的学生姓名
2.列出 2 门以上(含 2 门)不及格学生姓名及平均成绩。
select count(scgrade) as rejgradenum,sno from sc where scgrade<60 group by SNO having rejgradenum>=2;
//先找出不及格两门以上的学生的学号
select sname,avg(sc.scgrade) from s join (select count(scgrade) as rejgradenum,sno from sc where scgrade<60 group by SNO having rejgradenum>=2) t
on
t.sno =s.sno
join sc
on
sc.sno = t.sno;
//然后再查询学生的姓名,及他全部的成绩的平均成绩,所以t临时表和s可以查到学生姓名,再连接sc表可以将这个学生的全部成绩求平均.
+----------+-----------------+
| sname | avg(sc.scgrade) |
+----------+-----------------+
| student1 | 52.5 |
+----------+-----------------+
3.即学过 1 号课程又学过 2 号课所有学生的姓名。
select sno from sc where cno='1' ;
select sno from sc where cno='2' ;
//先查询出等于课程号等于1的学号,
//再查询出课程号等于2的学生的学号
select s.sname 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;
//查询课程号为1的学号和课程号为2的学号进行相等,抽取出学号,然后确定出选择一又选择二的学号,然后用确定的学号对s学生表进行匹配姓名,然后输出
14.列出所有员工及领导的姓名
select e.ename,ifnull(m.ename,'没有上级') from emp e left join emp m
on
e.mgr = m.empno;
//两张emp员工表进行连接,条件是e的mgr属性值等于m.empno属性值
+--------+----------------------------+
| ename | ifnull(m.ename,'没有上级') |
+--------+----------------------------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| KING | 没有上级 |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
+--------+----------------------------+
15、列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称
select mgr from emp;
select t.empno,t.deptno,t.ename
from
emp e
join
(select empno ,deptno,ename,mgr,date_format(t1.hiredate,'%Y%m%d') as tdate from emp t1) t
on
e.empno = t.mgr and t.tdate<date_format(e.hiredate,'%Y%m%d');
//先查询出来比上级早的员工姓名部门编号
+-------+--------+-------+
| empno | deptno | ename |
+-------+--------+-------+
| 7369 | 20 | SMITH |
| 7499 | 30 | ALLEN |
| 7521 | 30 | WARD |
| 7566 | 20 | JONES |
| 7698 | 30 | BLAKE |
| 7782 | 10 | CLARK |
+-------+--------+-------+
select
m.empno,m.ename,d.dname
from
dept d
join
(
select
t.empno,t.deptno,t.ename
from
emp e
join
(select
empno ,deptno,ename,mgr,date_format(t1.hiredate,'%Y%m%d') as tdate
from
emp t1) t
on
e.empno = t.mgr and t.tdate<date_format(e.hiredate,'%Y%m%d')) m
on
m.deptno = d.deptno
order by
empno asc;
+-------+-------+------------+
| empno | ename | dname |
+-------+-------+------------+
| 7369 | SMITH | RESEARCH |
| 7499 | ALLEN | SALES |
| 7521 | WARD | SALES |
| 7566 | JONES | RESEARCH |
| 7698 | BLAKE | SALES |
| 7782 | CLARK | ACCOUNTING |
+-------+-------+------------+
16.列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门
select d.dname,t.* from dept d left join (
select * from emp
) t
on
d.deptno = t.deptno;
//通过连接emp的*查询,同时设置left部门表为主表,因为其没有员工的部门也要输出.
//然后条件就是t表的部门编号等于d表的部门编号,然后输出dname,和t的全部
+------------+-------+--------+-----------+------+------------+---------+---------+--------+
| dname | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+------------+-------+--------+-----------+------+------------+---------+---------+--------+
| ACCOUNTING | 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| ACCOUNTING | 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| ACCOUNTING | 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
| RESEARCH | 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| RESEARCH | 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| RESEARCH | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| RESEARCH | 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| RESEARCH | 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| SALES | 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| SALES | 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| SALES | 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| SALES | 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| SALES | 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| SALES | 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| OPERATIONS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+------------+-------+--------+-----------+------+------------+---------+---------+--------+
17.列出至少有 5 个员工的所有部门
select deptno,count(*) num from emp group by deptno having num>=5;
//
select d.dname,t.num from dept d join (select deptno,count(*) num from emp group by deptno having num>=5) t on
d.deptno = t.deptno;
+----------+-----+
| dname | num |
+----------+-----+
| RESEARCH | 5 |
| SALES | 6 |
+----------+-----+
18.列出薪金比"SMITH"多的所有员工信息.
select sal from emp where
ename='smith'; //先查出smith的薪资
select t.* from emp t join (select sal from emp where
ename='smith') e on
t.sal >e.sal; //然后表连接输出比smith的sal大的员工信息
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 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 |
+-------+--------+-----------+------+------------+---------+---------+--------+
19.列出所有"CLERK"(办事员)的姓名及其部门名称,部门的人数.
select e.ename,e.empno,e.deptno from emp e where job='clerk';
//先查出工作是clerk的姓名编号的部门编号
select t.ename,d.dname,m.num from dept d join (select e.ename,e.empno,e.deptno from emp e where job='clerk') t on
t.deptno = d.deptno
//然后连接部门表查出部门名称,条件是部门编号等于部门编号
join (select deptno,count(deptno) as num from emp group by deptno) m
on
m.deptno = t.deptno;
//然后再查出这个部门的人数,通过部门编号
+--------+------------+-----+
| ename | dname | num |
+--------+------------+-----+
| SMITH | RESEARCH | 5 |
| ADAMS | RESEARCH | 5 |
| JAMES | SALES | 6 |
| MILLER | ACCOUNTING | 3 |
+--------+------------+-----+
20、列出最低薪金大于 1500 的各种工作及从事此工作的全部雇员人数.
select e.job from emp e group by job having min(sal)>1500;
//先查出最低薪资大于1500的工作是什么
select e2.job,count(e2.job) from emp e2 join (select e.job from emp e group by job having min(sal)>1500) t on
t.job = e2.job
group by job;
//然后再查出这个工作有多少人,通过表连接,然后通过工作分组分组
+-----------+---------------+
| job | count(e2.job) |
+-----------+---------------+
| ANALYST | 2 |
| MANAGER | 3 |
| PRESIDENT | 1 |
+-----------+---------------+
21.列出在部门"SALES"<销售部>工作的员工的姓名,假定不知道销售部的部 门编号.
1.select ename,job from emp where deptno not in (10,20,40);
+--------+----------+
| ename | job |
+--------+----------+
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| MARTIN | SALESMAN |
| BLAKE | MANAGER |
| TURNER | SALESMAN |
| JAMES | CLERK |
+--------+----------+
22.列出薪金高于公司平均薪金的所有员工,所在部门,上级领导,雇员的工资等 级.
select avg(sal) as avgsal from emp;
//先查询出公司的平均工资avgsal
select e.ename,e.sal,d.dname,e2.ename,s.grade from emp e join (select avg(sal) as avgsal from emp) t
on
e.sal > t.avgsal
join dept d
on
d.deptno = e.deptno
left join emp e2
on
e.mgr = e2.empno
join salgrade s
on
e.sal between s.losal and s.hisal;
//然后再跟emp连接,查出大于avgsal的名字,工资,等,
再跟部门表连接。查出部门名称,
再跟emp连接一下,然后设置左为主表,查出前面的符合要求的员工的上级领导的编号。
再与工资表连接,查出前面工资的等级,结束
+-------+---------+------------+-------+-------+
| ename | sal | dname | ename | grade |
+-------+---------+------------+-------+-------+
| JONES | 2975.00 | RESEARCH | KING | 4 |
| BLAKE | 2850.00 | SALES | KING | 4 |
| CLARK | 2450.00 | ACCOUNTING | KING | 4 |
| SCOTT | 3000.00 | RESEARCH | JONES | 4 |
| KING | 5000.00 | ACCOUNTING | NULL | 5 |
| FORD | 3000.00 | RESEARCH | JONES | 4 |
+-------+---------+------------+-------+-------+
23.列出与"SCOTT"从事相同工作的所有员工及部门名称.
select e.job from emp e where ename='scott';
select e2.ename,e2.deptno,d.dname from emp e2 join (select e.job from emp e where ename='scott') t
on
e2.job = t.job
join dept d
on
d.deptno = e2.deptno
where e2.ename <> 'scott';
+-------+--------+----------+
| ename | deptno | dname |
+-------+--------+----------+
| FORD | 20 | RESEARCH |
+-------+--------+----------+
24、列出薪金等于部门 30 中员工的薪金的其他员工的姓名和薪金.
select e2.sal,e2.ename from emp e2 join (select e.sal from emp e where deptno=30) s on e2.sal=s.sal where deptno!=30 ;
然后在进行表的连接,查找薪资等于t的员工信息,并且条件是部门不等于30
结果为空!
---------------------------------------------------
25、列出薪金高于在部门 30 工作的所有员工的薪金的员工姓名和薪金.部门名 称.
select distinct e2.sal,e2.ename,d.dname from emp e2 join (select max(e.sal) sal from emp e where deptno=30) s on e2.sal>s.sal
join dept d on e2.deptno=d.deptno
where e2.deptno!=30 ;
//大于,所以是>,并且连接部门,然后连接部门表查询部门名称
+---------+-------+------------+
| sal | ename | dname |
+---------+-------+------------+
| 2975.00 | JONES | RESEARCH |
| 3000.00 | SCOTT | RESEARCH |
| 5000.00 | KING | ACCOUNTING |
| 3000.00 | FORD | RESEARCH |
+---------+-------+------------+
26、列出在每个部门工作的员工数量,平均工资和平均服务期限.
select count(*) num,avg(sal) as avgsal,ceil(avg(date_format(now(),'%Y')-date_format(hiredate,'%Y'))) avgyear from emp group by deptno;
//查询数量 平均工资 平均服务年限,通过ceil方法进行向上取整
+-----+-------------+---------+
| num | avgsal | avgyear |
+-----+-------------+---------+
| 3 | 2916.666667 | 41 |
| 5 | 2175.000000 | 39 |
| 6 | 1566.666667 | 41 |
+-----+-------------+---------+
27、列出所有员工的姓名、部门名称和工资
select e.ename,d.dname,sal from emp e join
dept d
on
e.deptno= d.deptno;
//两个表的连接,比较简单
+--------+------------+---------+
| ename | dname | sal |
+--------+------------+---------+
| CLARK | ACCOUNTING | 2450.00 |
| KING | ACCOUNTING | 5000.00 |
| MILLER | ACCOUNTING | 1300.00 |
| SMITH | RESEARCH | 800.00 |
| JONES | RESEARCH | 2975.00 |
| SCOTT | RESEARCH | 3000.00 |
| ADAMS | RESEARCH | 1100.00 |
| FORD | RESEARCH | 3000.00 |
| ALLEN | SALES | 1600.00 |
| WARD | SALES | 1250.00 |
| MARTIN | SALES | 1250.00 |
| BLAKE | SALES | 2850.00 |
| TURNER | SALES | 1500.00 |
| JAMES | SALES | 950.00 |
+--------+------------+---------+
28.列出所有部门的详细信息和人数
select d.*,count(e.deptno) '人数' from dept d left join emp e
on
e.deptno = d.deptno
group by e.deptno;
//这里选择左边的表为主表,因为40编号的部门没有人员,若不为主表则匹配deptno不成功,则会被筛掉,所以设为主表.
//2.然后查人数时,要以e.deptno来查,因为e.deptno在40编号的部门为0,才能输出正确.
//若以d.deptno来查count时,40部门会查出1,主表的40部门没有匹配也会被当作一个成功的值
+--------+------------+----------+------+
| DEPTNO | DNAME | LOC | 人数 |
+--------+------------+----------+------+
| 40 | OPERATIONS | BOSTON | 0 |
| 10 | ACCOUNTING | NEW YORK | 3 |
| 20 | RESEARCH | DALLAS | 5 |
| 30 | SALES | CHICAGO | 6 |
+--------+------------+----------+------+
29.列出各种工作的最低工资及从事此工作的雇员姓名
select e.job,min(sal) minsal from emp e group by job;
//先查找出工作和最低工资是多少
select t.* from emp t join (select e.job,min(sal) minsal from emp e group by job) m
on
m.job = t.job and m.minsal =t.sal;
//然后再进行表连接,查找所有.t表与m临时表进行连接,条件是工作相匹配并且工资相匹配
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 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 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
+-------+--------+-----------+------+------------+---------+---------+--------+
30、列出各个部门的 MANAGER(领导)的最低薪金
select
e.deptno,min(e.sal)
from
emp e
where
e.job ='manager'
group by
deptno;
//通过emp表的查询,然后条件是工作是manager的,并且再通过deptno部门编号分组,就可以查到部门的最低manager的薪资了.
+--------+------------+
| deptno | min(e.sal) |
+--------+------------+
| 10 | 2450.00 |
| 20 | 2975.00 |
| 30 | 2850.00 |
+--------+------------+
31、列出所有员工的年工资,按年薪从低到高排序
select
ename,(sal*12+ifnull(comm,0)) yearsal
from
emp
order by
yearsal asc;
//年薪,通过sal*12加上comm补助,若为空,则设置为0
+--------+----------+
| ename | yearsal |
+--------+----------+
| SMITH | 9600.00 |
| JAMES | 11400.00 |
| ADAMS | 13200.00 |
| WARD | 15500.00 |
| MILLER | 15600.00 |
| MARTIN | 16400.00 |
| TURNER | 18000.00 |
| ALLEN | 19500.00 |
| CLARK | 29400.00 |
| BLAKE | 34200.00 |
| JONES | 35700.00 |
| FORD | 36000.00 |
| SCOTT | 36000.00 |
| KING | 60000.00 |
+--------+----------+
32、求出员工领导的薪水超过 3000 的员工名称与领导名称
select
e.ename,e.mgr
from emp;
//先查询emp中mgr与name
select
t.ename,m.ename
from emp t
join
(select e.ename,e.mgr from emp e) m
on
m.mgr = t.empno
where
t.sal>3000;
//再通过表连接,进行查询,条件是mgr等于empno,则输出这个empno的name
+-------+-------+
| ename | ename |
+-------+-------+
| KING | JONES |
| KING | BLAKE |
| KING | CLARK |
+-------+-------+
33、求出部门名称中,带’S’字符的部门员工的工资合计、部门人数.
select d.deptno,d.dname from dept d where d.dname like '%s%';
//首先查出带s的部门,为3个
+--------+------------+
| deptno | dname |
+--------+------------+
| 20 | RESEARCH |
| 30 | SALES |
| 40 | OPERATIONS |
+--------+------------+
select t.dname,sum(e.sal),count(e.deptno) from emp e right join (select d.deptno,d.dname from dept d where d.dname like '%s%') t
on
e.deptno = t.deptno
group by t.deptno;
//然后再通过表的连接,进行查询工资的合计和人数,条件为部门编号等于部门编号,通过部门编号分组
+------------+------------+-----------------+
| dname | sum(e.sal) | count(e.deptno) |
+------------+------------+-----------------+
| RESEARCH | 10875.00 | 5 |
| SALES | 9400.00 | 6 |
| OPERATIONS | NULL | 0 |
+------------+------------+-----------------+
34、给任职日期超过 30 年的员工加薪 10%.
select date_format(now(),'%Y')-date_format(e.hiredate,'%Y') isPth from emp e;
//查出大于三十的,检查有没有,结果为有,(并且全部)
+-------+
| isPth |
+-------+
| 42 |
| 41 |
| 41 |
| 41 |
| 41 |
| 41 |
| 41 |
| 35 |
| 41 |
| 41 |
| 35 |
| 41 |
| 41 |
| 40 |
+-------+
update
emp
set
sal=1.1*sal
where
(date_format(now(),'%Y')-date_format(hiredate,'%Y')) >30;
//更新emp表中sal= 1.1sal,并且条件为现在时间减去入职日期是否大于30,用到了date_fromat转换为字符串.
//更新之前的表
+-------+--------+-----------+------+------------+---------+---------+--------+
| 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 |
+-------+--------+-----------+------+------------+---------+---------+--------+
//更新之后的表
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 880.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1760.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1375.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 3272.50 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1375.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 3135.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2695.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3300.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5500.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1650.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1210.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 1045.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3300.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1430.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+