MySQL从入门到精通(二)

一、建表语句

DROP TABLE IF EXISTS EMP;
DROP TABLE IF EXISTS DEPT;
DROP TABLE IF EXISTS SALGRADE;
 
CREATE TABLE DEPT
       (DEPTNO int(2) not null ,
	DNAME VARCHAR(14) ,
	LOC VARCHAR(13),
	primary key (DEPTNO)
	);
CREATE TABLE EMP
       (EMPNO int(4)  not null ,
	ENAME VARCHAR(10),
	JOB VARCHAR(9),
	MGR INT(4),
	HIREDATE DATE  DEFAULT NULL,
	SAL DOUBLE(7,2),
	COMM DOUBLE(7,2),
	primary key (EMPNO),
	DEPTNO INT(2) 
	)
	;
 
CREATE TABLE SALGRADE
      ( GRADE INT,
	LOSAL INT,
	HISAL INT );
 
 
 
 
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 
10, 'ACCOUNTING', 'NEW YORK'); 
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 
20, 'RESEARCH', 'DALLAS'); 
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 
30, 'SALES', 'CHICAGO'); 
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 
40, 'OPERATIONS', 'BOSTON'); 
commit;
 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7369, 'SMITH', 'CLERK', 7902,  '1980-12-17'
, 800, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7499, 'ALLEN', 'SALESMAN', 7698,  '1981-02-20'
, 1600, 300, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7521, 'WARD', 'SALESMAN', 7698,  '1981-02-22'
, 1250, 500, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7566, 'JONES', 'MANAGER', 7839,  '1981-04-02'
, 2975, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7654, 'MARTIN', 'SALESMAN', 7698,  '1981-09-28'
, 1250, 1400, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7698, 'BLAKE', 'MANAGER', 7839,  '1981-05-01'
, 2850, NULL, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7782, 'CLARK', 'MANAGER', 7839,  '1981-06-09'
, 2450, NULL, 10); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7788, 'SCOTT', 'ANALYST', 7566,  '1987-04-19'
, 3000, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7839, 'KING', 'PRESIDENT', NULL,  '1981-11-17'
, 5000, NULL, 10); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7844, 'TURNER', 'SALESMAN', 7698,  '1981-09-08'
, 1500, 0, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7876, 'ADAMS', 'CLERK', 7788,  '1987-05-23'
, 1100, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7900, 'JAMES', 'CLERK', 7698,  '1981-12-03'
, 950, NULL, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7902, 'FORD', 'ANALYST', 7566,  '1981-12-03'
, 3000, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7934, 'MILLER', 'CLERK', 7782,  '1982-01-23'
, 1300, NULL, 10); 
commit;
 
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES ( 
1, 700, 1200); 
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES ( 
2, 1201, 1400); 
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES ( 
3, 1401, 2000); 
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES ( 
4, 2001, 3000); 
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES ( 
5, 3001, 9999); 
commit;
 

 

二、数据排序asc、desc

含义

排序采用 order by 子句,order by 后面跟上排序字段,排序字段可以放多个,多个采用逗号间隔,order by默认采用升序(asc),如果存在 where 子句,那么 order by 必须放到where 询句后面。

1.按照薪水由小到大排序(系统默认由小到大)

select ename,sal from emp order by sal;

2.取得job为MANAGER的员工,按照薪水由小到大排序(系统默认由小到大)

select ename,job,sal from emp where job = 'MANAGER' order by sal;

3.按照job和薪水倒序排序

select ename,job,ename from emp order by job desc,sal desc;

注:如果采用多个字段排序,如果根据第一个字段排序重复了,会根据第二个字段排序

三、处理函数(单行处理)

1.数据处理函数(单行处理函数)

Lower

转换小写

upper 转换大写
substr 取子串(substr(被截取的字符串,起始下标,截取的长度))
length 取长度
trim 去空格
str_to_date 将字符串转换成日期
date_format 格式化日期
format 设置干分位
round 四舍五入
rand() 生成随机数
ifnull 可以将null转换成一个具体值

2.lower(字段名)函数:转换为小写

用法:lower(要转换的字段)

查询员工姓名,将员工姓名全部转换成小写

select lower(ename) as ename from emp;

3.upper(字段名)函数:转换为大写

用法:upper(要转换字段名称)

查询员工姓名,将员工姓名全部转换成大写

select upper(ename) as ename from emp;

4.substr(字段名,起始下标,截取长度)函数:取子串

用法:substr(字段名,起始下标,截取长度)

注意:起始下标:从1开始

1)查询并显示所有员工姓名的第二个字母

select substr(ename,2,1) from emp;

2)查询员工姓名中第二个字母为A的所有员工

select ename from emp where substr(ename,2,1) = 'A'

5.length(字段名)函数:取字段长度

用法:length(字段名称)

取得员工姓名长度

select ename,length(ename) as nameLength from emp;

6.ifnull(字段名,替换值)函数:空值处理函数

用法:ifnull(字段名称,将要替换)

结论:在数据库中,有NULL参与数学运算的结果一定为NULL;为了防止计算结果出现NULL,建议先使用ifnull函数预先处理

1)查询员工姓名及补助,如果补助为NULL设置为0

select ename,ifnull(comm,0) from emp;

2)查询员工薪水与补助的和

select sal+ifnull(comm,0) from emp;

3)没有补助的员工,将每月补助100,求员工的年薪

select ename,(sal+ifnull(comm,100)) * 12 yearsal from emp;

7.case..when..then..else..end

匹配工作岗位,当MANAGER时,薪水上调10%,当为SALESMAN时,薪水上调50%,其他岗位薪水不变

select ename,sal,job,
    (case job
        when 'MANAGER' then sal*1.1
        when 'SALESMAN' then sal*1.5
    else sal
    end) as newsal
from
    emp;

8.trim(‘字符串’)函数:去除首尾空格

作用:trim函数去除首尾空格,不会去除中间空格

用法:trim(字符串)

取得工作岗位为manager的所有员工

select * from emp where job = trim('    manager   ');

9.round(数字,保留小数位数)函数:四舍五入

用法:round(要四舍五入的数字,四舍五入到哪一位),默认保留整数位

10.rand()函数:生成随机数

select round(rand()*100,0);

11.str_to_date函数:将字符串转换为日期

作用:将‘日期字符串’ 转换为 ‘日期类型’数据

用法:str_to_date('日期字符串',‘日期格式’)

日期字符串:日期格式的字符串

日期格式:告知MySQL输入日期字符串的格式是什么

MySQL日期格式:

序号 格式符 功能   格式符 功能
1 %Y 代表四年的年份   %y 代表两位的年份
2 %m 代表月,格式(01..12)   %c 代表月,格式(1...12)
3 %d 代表日      
4 %H 代表24小时制   %h 代表12小时制
5 %i 代表分钟,格式(00...59)      
6 %S或%s 代表秒,格式(00..59)      

1)查询出1981-12-03入职的员工

select ename,hiredate from emp where hiredate = '1981-12-03';

原因:

1、在MySQL中日期作为查询条件时:可以使用字符串为其赋值

2、输入的日期字符串格式与MySQL默认日期格式相同

2)查询出02-20-1981入职的员工

select ename,hiredate from emp where hiredate = str_to_date('02-20-1981','%m-%d-%Y');

12.date_format函数:将日期转换为特定格式字符串

作用:‘将日期类型’转换为特定格式的‘日期字符串’类型

用法:date_format(日期类型数据,;'日期格式')

1)查询员工的入职日期,以‘10-12-1980’的格式显示到窗口中

select ename,date_format(hiredate,'%m-%d-%Y') hiredate from emp;

2)查询员工的入职日期,以'10/12/1980'的格式显示到窗口中

​
select ename,date_format(hiredate,'%m/%d/%Y') hiredate from emp;

结论:date_format函数主要用在数据库查询操作中。实际工作中,客户需要日期以特定格式展示的时候,需要使用该函数

四、分组函数/聚合函数/多行处理函数

1.常见函数

sum 求和
avg 取平均
max 取最大值
min 取最小值
count 取得记录数

2.单行/多行处理函数

单行处理函数:一行输入对应一行输出

多行处理函数:多行输入对应一行输出

注:

1、分组函数自动忽略控制,不需要手动增加where条件排除空值;

2、分组函数不能直接使用在where关键字后面;

3.sum(字段)函数

作用:求某一列的和,null会自动被忽略;

用法:sum(字段名称)

1)取得薪水总计

select sum(sal) from emp;

2)取得补助总计

select sum(comm) from emp;

3)取得总共薪水(工资+补助)合计

select sum(sal + ifnull(comm,0)) from emp

4.avg(字段名)函数

作用:求某一列的平均值,null会被自动忽略

用法:avg(字段名称)

取得平均薪水avg(sal)

select avg(sal) as avgsal from emp

5.max(字段名)函数

作用:取得某一列的最大值

用法:max(字段名称)

1)取得最高薪水max(sal)

select max(sal) from emp;

2)取得最晚入职的员工max(sal)

select max(hiredate) from emp;

6.min(字段名)函数

作用:取得某一列最小值

用法:min(字段名称)

1)取得最低薪水max(sal)

select min(sal) from emp;

2)取得最早入职的员工max(sal)

select min(hiredate) from emp;

7.count函数

作用:取得某字段值不为null的记录总数

用法:count(字段名称)或count(*)

注意:

1、count(*)表示取得当前查询表所有记录

2、count(字段名称),不会统计为null的记录

1)取得所有员工数

select count(*) from emp;

2)取得补助不为空的所有员工数

select count(comm) from emp;

3)取得补助为空的员工数量

select count(*) from emp where comm is null;

8.distinct去除重复记录

作用:将查询结果中某一字段的重复记录去除掉

用法:distinct字段名或distinct 字段名1,字段名2

distinct 字段名A:去除与字段名A相同的记录

distinct字段名A,字段名B:去除与字段A和字段B同时相同的记录

注意:distinct只能出现在所有字段最前面,后面如果有多个字段及为多字段联合去重

1)查询该公司有哪些工作岗位

select distinct job from emp

2)查询该公司工作岗位数量

select count(distinct job) from emp;

3)去除部门编号deptno和工作岗位job重复记录

select distinct deptno,job from emp

9.分组查询:group by

作用:通过哪个或哪些字段进行分组

用法:group by 字段名称

1)找出每个工作岗位的最高薪水

select job,max(sal) from emp group by job

结论:有group by的DDL语句中,select语句后面只能跟分组函数+参与分组的字段

2)计算每个工作岗位的最高薪水,并且按照由低到高进行排序

思路分析:先按照工作岗位job进行分组,然后对每一组薪水求最大值max,最后在根据每一组薪水的最大值进行由低到高排序

select job,max(sal) as maxsal from emp group by job order by maxsal

注意:如果使用了order by,order by必须放到group by 后面

3)计算每个部门的平均薪水

思路分析:首先,按照部门编号分组,然后对每一组的薪水求平均值

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

4)计算不同部门不同岗位的最高薪水

思路分析:首先把deptno和job看成一个字段进行联合字段分组,联系到distinct关键字

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

5)找出每个工作岗位的最高薪水,出MANAGER之外

思路分析:先将job等于MANAGER的过滤掉,然后再根据工作岗位进行分组,对每一组求最大薪水

select job,max(sal) as maxsal from emp where job <> 'MAXAGER' group by job;

10.having

作用:如果想对分组的数据再进行过滤,需要使用having子句

找出每个工作岗位的平均薪水,要求显示平均薪水大于2000的

思路分析:先对工作岗位job分组,然后对每一组薪水求平均值,最后再对每一组平均薪水的值进行大于2000的条件过滤

select job,avg(sal) from emp group by job having avg(sal) > 2000

11.where与having区别

1)where和having都是为了完成数据的过滤,他们后面都是添加条件

2)where是在group by之前完成过滤

3)having是在group by之后完成过滤

五、select语句总结

一个完整的SQL语句如下:

select
    xxxx
from
    xxxx
where
    xxxx
group by
    xxxx
having
    xxxx
order by
    xxxx

1)from将硬盘上的表文件加载到内存

2)where将符合条件的数据进行摘取出来,生成一张新的临时表

3)group by根据列中的数据种类,将当前临时表划分成若干个新的临时表

4)having可以过滤掉group by生成的不符合条件的临时表

5)select对当前临时表进行整列读取

6)order by对select生成的临时表,进行重新排序,生成新的临时表

7)limit对最终生成的临时表的数据行,进行截取

发布了98 篇原创文章 · 获赞 148 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_40310148/article/details/102962158