mysql-day02

SQL-DDL

-- 一个标准的数据库脚本写法,   注意,数据库脚本的扩展名.sql

-- 创建数据库mydb, 设置编码集 UTF8
create database if not exists mydb character set utf8;
-- 切换到mydb数据库
use mydb;

-- 删除emp表结构
drop table if exists emp;

-- 创建emp表结构
create table if not exists `EMP`(
`EMPNO` 		int(4)  comment '员工编号',
`ENAME` 		varchar(10) comment '员工姓名',
JOB  		varchar(9) comment '员工职位',
MGR 		int(4) comment '员工的直属领导编号,注意,领导也是员工,领导的信息也在这个表中',
HIREDATE 	date comment '入职日期',
SAL 		int(7) comment '员工工资',
COMM 		int(7) comment '员工奖金',
DEPTNO 		int(2) comment '员工所在部门编号'
) comment '员工信息表';
-- 查询表中的数据
select * from emp;
-- 查看表结构
desc emp;
-- 清空表数据
delete from emp;

-- 插入数据
insert into emp values
(7369,'SMITH','CLERK',7902,'1980-12-17',800,null,20),
(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30),
(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30),
(7566,'JONES','MANAGER',7839,'1981-04-02',2975,null,20),
(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30),
(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,null,30),
(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,null,10),
(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,null,20),
(7839,'KING','PRESIDENT',null,'1981-11-17',5000,null,10),
(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30),
(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,null,20),
(7900,'JAMES','CLERK',7698,'1981-12-03',950,null,30),
(7902,'FORD','ANALYST',7566,'1981-12-02',3000,null,20),
(7934,'MILLER','CLERK',7782,'1982-01-23',1300,null,10);
-- 查询表记录
select * from emp;

-- 删除dept表结构
drop table if exists dept;
-- 创建detp表结构
create table if not exists DEPT(
DEPTNO    	int(2) comment '部门编号',
DNAME     	varchar(14) comment '部门名称',
LOC 		varchar(13) comment '部门所在城市'
) comment '部门信息表';
-- 清空表记录
delete from dept;
-- 插入表记录
insert into dept values (10,'ACCOUNTING','NEW YORK');
insert into dept values (20,'RESEARCH','DALLAS');
insert into dept values (30,'SALES','CHICAGO');
insert into dept values (40,'OPERATIONS','BOSTON');
-- 查询表记录
select * from dept;




-- ---------------------------------------------
--                           DQL语言的学习
-- ---------------------------------------------

-- 最简单的查询语句,有两个子句:分别是select和from

-- 练习1:查询员工表中的所有记录     *表示表中的所有字段
select * from emp;     
-- 练习2: 查询员工表中的员工姓名,职位,入职日期,所在部门编号
select ename,job,hiredate,deptno from emp;


-- 别名的用法:   可以给表起别名,也可以给列起别名
select ename 姓名, job '职位', hiredate as "入职日期" ,deptno 部门编号 from emp as 员工表;
select emp.* from emp;
select a.* from emp a;
select emp.* from emp a; -- 命名了别名,就必须使用别名。


-- ------------------------------------------------------------------
--  where 子句的应用
-- ------------------------------------------------------------------
-- 练习1: 查询工资大于2000的员工编号,姓名,职位,工资
select empno,ename,job,sal from emp where sal > 2000;
-- 练习2: 查询20号部门,工资大于2000的员工姓名,职位,工资,部门编号
select ename,job,sal,deptno from emp where deptno = 20 and sal > 2000;
-- 练习3:查询不是20号部门,工资在1000~2000范围内的员工信息
select * from emp where deptno <> 20  and sal >=1000 and sal <=2000; 
select * from emp where deptno <> 20  and sal between 1000 and 2000; 
-- 练习4:查询10 和 20 号部门的员工编号大于7500的员工信息
select * from emp where deptno =10 or deptno =20 and empno >7500;
select * from emp where deptno in (10,20) and empno >7500;
-- 练习5:查询1981年入职的员工信息
select * from emp where hiredate >= '1981-1-1' and hiredate < '1982-1-1';
select * from emp where YEAR(hiredate) = 1981;
-- 练习6:查询职位不是 ANALYST、SALESMAN、MANAGER的员工信息
select * from emp where job != 'ANALYST' and job !='SALESMAN' and job != 'MANAGER';
select * from emp where job not in ('ANALYST','SALESMAN','MANAGER');
-- 练习7:查询员工姓名是A开头的员工编号,姓名,职位
select empno,ename,job from emp where ename like 'A%'; 
-- 练习8:查询员工姓名为5个长度的员工编号,姓名,职位
select empno,ename,job from emp where ename like '_____'; 
-- 练习9: 查询员工姓名中第二个字母是A的,职位不是CLERK的员工编号,姓名,职位
select empno,ename,job from emp where ename like '_A%' and job !='CLERK'; 


-- ------------------------------------------------------------------
-- ----------------------group by 子句的应用-------------------------
-- 应用场景:对表中的记录进行分组,比如按照部门、职位、地区、年龄、性别、季度等字段进行分组,
--           对每一组中的数据进行统计,统计总条数,和,平均值,最大值,最小值等
--           一般情况下,每一组统计完,都是一条记录。
--           比如: 表中的数据可以按照部门分组,分三组,最终统计的结果,就是三行记录。
-- 语法:  group by 分组字段1[,分组字段2....] 
-- 注意事项:
--     1. select子句中 除了用于统计的函数外,只能放分组字段,如果放入其他字段没有意义。
--     2. 函数(聚合函数,分组函数):
--        count(*|常量|字段名): 统计该组中的所有记录总数
--        sum(常量|字段名): 如果是常量,则统计的是该组中所有记录个常量的和
--        avg(常量|字段名):同上,只不过是求平均值。  使用总和除以总条数
--        max(字段名): 返回该组中的指定字段里的最大值
--        min(字段名): 返回该组中的指定字段里的最小值 
--     3. null值处理:
--        当在聚合函数中使用字段名时,如果该组中的这个字段在某些行上可能存在null。 默认情况下
--        null值所在行不会被统计在内。因此可能会影响最终结果。
--        此时,需要使用ifnull函数对null值进行处理,
--        语法:ifnull(字段名,defaultValue): 
--        逻辑:if(字段值==null) defaultValue else 字段值
--        一般情况下: avg要使用的。 
-- ------------------------------------------------------------------

-- 练习1:统计每个部门的人数
select deptno,count(*) from emp group by deptno;
select deptno,count(1) from emp group by deptno;
-- 练习2:统计每年入职的人数
select year(hiredate),count(*) from emp group by year(hiredate);
-- 练习3:统计每种职位的人数
select job,count(*) from emp group by job;
-- 练习4:统计每个部门不同职位的人数
select deptno,job,count(*) from emp group by deptno,job;      
-- 练习5:统计每个部门的人数,工资总和,平均工资,最高工资,最低工资。
select 
deptno,
count(*) 总人数, 
sum(sal) 工资之和, 
avg(ifnull(sal,0)) 平均工资,
max(sal) 最高工资,
min(sal) 最低工资
from emp group by deptno;
-- 练习6:统计每个部门的每种职位的人数、工资之和、平均工资
SELECT
	deptno,
	job,
	count( 1 ),
	sum( sal ),
	avg( ifnull( sal, 0 ) ) 
FROM
	emp 
GROUP BY
	deptno,
	job;
-- 练习7:统计每个部门的人数,奖金之和,平均奖金,最低奖金,最高奖金。
SELECT deptno, COUNT(1)
	, SUM(ifnull(comm, 0))
	, AVG(ifnull(comm, 0))
	, MIN(ifnull(comm, 0))
	, MAX(if(comm, 0))
FROM emp
GROUP BY deptno;
-- 练习8: 查询部门表中的总人数,最高工资,最低工资,平均奖金,奖金之和。
--        如果没有使用group by子句,而在select子句中使用聚合函数,那就表示整张表为一组,进行统计。
select count(1),max(sal),min(sal),avg(ifnull(comm,0)),sum(comm) from emp;


-- 练习9: 使用select 计算1和2 的和。
select 1+2;
select 10-2;
select 10*3;
select 10/3;
select 10%3;

-- 练习10: 基于表,在select子句中使用常量。 则会给每一行记录分配一个常量
select 100,a.* from emp a;
-- 比如: 统计表中的记录总数
select sum(1),count(0),count(*) from emp;





-- ------------------------------------------------------------------
-- ----------------------having 子句的应用---------------------------
-- 应用场景: 分组后,继续过滤和筛选。
--     位置:  位于group by子句后
--     语法: having condition
-- ------------------------------------------------------------------
-- 练习1:查询部门平均工资大于1600部门号,平均工资。
select deptno,avg(ifnull(sal,0)) avg_sal from emp group by deptno having avg_sal >1600;
-- 练习2:查询每种职位的最高工资大于1500的职位、最高工资,平均工资,平均奖金。
select job,max(sal),avg(ifnull(sal,0)),avg(ifnull(comm,0)) from emp group by job having max(sal)>1500;



-- ------------------------------------------------------------------
-- ----------------------order by 子句的应用-------------------------
-- 应用场景: 对查询出来的数据,进行排序。  按照某些字段升序或者降序
-- ----语法:  order by colName [asc|desc] [,colName [asc|desc]] 
--             asc:    升序, 默认情况就是升序,可以省略不写
--             desc:   降序
-- 执行顺序:位于select子句后
-- ------------------------------------------------------------------
-- 练习1:查询员工表中的所有员工信息,按照工资降序排序
select * from emp  order by sal desc;
-- 练习2:查询员工表中的所有员工信息,按照工资降序排序,如果相同,再按照奖金降序排序
select * from emp  order by sal desc,comm desc;




-- ------------------------------------------------------------------
-- ----------------------distinct关键字-------------------------
-- 应用场景:   当查询出来的记录(整行内容)有重复的, 而我们不需要重复数据,就可以使用distinct
--     位置:   紧随select关键字之后
-- ------------------------------------------------------------------

-- 练习1:查询有哪些部门编号
select distinct deptno from emp;
-- 练习2:查询有哪些职位名称
select distinct job from emp;
-- 练习3:查询有哪些部门以及部门中有哪些职位
select distinct deptno,job from emp order by deptno;




-- ------------------------------------------------------------------
-- ----------------------limit关键字-------------------------
-- 应用场景:   当一页的数据量过大时,我们可以进行关键字limit进行分页显示操作。
--     注意:分页查询时,一般都要进行先排序,再分页。
--     语法:limit m[,n];
--                m      表示从index处开始查询,   
--                n      表示要查询的记录数目。 
--     注意:
--           1. mysql的记录索引index从0开始。
--           2. 只有一个参数时,比如limit n   表示从第一行开始查询n条记录
-- ------------------------------------------------------------------
-- 练习1: 按照工资降序,查询前五条记录
select * from emp order by sal desc limit 5;
select * from emp order by sal desc limit 0,5;
-- 练习2: 按照工资降序,查询第二个五条记录
select * from emp order by sal desc limit 5,5;
-- 练习3: 按照工资降序,查询第3条到第10条记录
select * from emp order by sal desc limit 2,8;
-- 练习4: 分页查询,工资降序,规定每页5条记录,查询第三页的数据。
select * from emp order by sal desc limit 10,5;
-- 练习5: 分页查询,工资降序,规定每页3条记录,查询第1页的数据。
select * from emp order by sal desc limit 0,3;
-- 练习6: 分页查询,工资降序,规定每页3条记录,查询第2页的数据。
select * from emp order by sal desc limit 3,3;
-- 练习7: 分页查询,工资降序,规定每页3条记录,查询第3页的数据。
select * from emp order by sal desc limit 6,3;
-- 练习8: 分页查询,工资降序,规定每页pageSize条记录,查询第page页的数据。
select * from emp order by sal desc limit (page-1)*pageSize,pageSize;


SQL-Function

-- -----------------------------------------
-- musql中常用的函数
-- 常用函数分为三大类,分别是日期函数,字符串函数,数值函数
-- -----------------------------------------

-- -----------------------------------
-- 第一类:日期函数的学习
-- -----------------------------------

-- 第一个:获取系统的当前日期和时间的函数
select now(),curdate(),curtime(),sysdate(),current_timestamp();
-- 第二个:获取星期几  dayofweek:星期日是1
--                     weekday:星期日是6
--                     dayname:获取星期的英语单词
select dayOfweek(now()),weekday(sysdate()),dayname(now());
-- 第三个:获取第几天
select DAYOFMONTH('2002-03-23'),DAYOFYEAR(now()),MONTHNAME(now());
-- 第四个:获取时间日期分量
select hour(now()),MINUTE(now()),second(now()),year(now()),month(now()),date(now());
-- 第五个:将日期时间格式化成我们想要的字符串形式
--                     %H:24小时制   %h:12小时制
select DATE_FORMAT(now(),'%Y/%m/%d %h:%i:%s %p %W');
-- 第六个:日期运算函数 date_add(date,interval express unit)/date _sub(date,interval express unit)
--                      adddate(date,interval express unit)/subdate(date,interval express unit);
-- 获取明日的此时此刻的时间
select adddate(now(),interval 1 day);
-- 获取12小时之前的时间
select adddate(now(),interval -12 hour);





-- -------------------------------------------
-- 第二类:字符串函数的学习
-- -------------------------------------------

-- 1. 进制转换函数 conv(n,from_base,to_base):对指定进制from_base的表现形式
select conv(12,10,8);
select conv(0xfabc,16,10);
-- 2. concat(v1,v2,v3):将多个参数拼接成一个字符串,只要有一个null,就返回null
select ename,job,concat(ename,"|",job) from emp;
-- 3. lpad(str,len,padstr)rpad(str,len,padstr): 使用指定的字符串从左/右填充原来的字符串
--     从左填充,就是向右靠齐
--     从右填充,就是向左靠齐
select lpad(ename,10,'#') from emp;
-- 4. 截取子串 left(str,len) /right(str,len) /substring(str,pos[,len]) 字符串下标从1开始
select left("www.baidu.com",9), right('www.baidi.com',3),substring('www.baidu.com',5,5);
-- 5. length(str) /octet_lenth(str): 返回参数对应默认字符集的所有字节数
select length("www.bardu.com"),length("张三丰");
-- 6. char_length(str)  character_length(str): 返回的是字符个数
select char_length("www.bardu.com"),character_length("张三丰");
-- 7. lirim(str) rteim(str) trim(str): 去掉字符串左/右/两端的空字符串
select char_length("abcd"),
ltrim("abcd"),char_length(ltrim("abcd")),
rtrim("abcd"),char_length(ltrim("abcd")),
trim("abcd"),char_length(ltrim("abcd"));
-- 8. lcase(str) lower(str) ucase(str) upper(str): 返回子母的大小写\
-- 查询姓名中带有a的所有员工信息
select * from emp where ename like '%a%';
select * from emp where upper(ename) like '%A%';
-- 9. replace(str,oldStr,newStr): 使用newStr子串替换掉oldStr
select replace('www.baidu.com','com','cn');
-- 10. insert(str,pos,len,newstr): 使用newStr替换str里的部分子串,从pos开始len个长度。
select insert('www.baidu.com',2,4,'####');





-- -----------------------------------
-- 第三类:数值函数的学习
-- -----------------------------------

-- pow(x,y)/power(x,y)返回值x的y次幂
select pow(8,3),power(8,3);
-- sqrt(n)返回非负数n的平方根
select sqrt(64);
select sqrt(2);

-- pi()  返回圆周率
select pi();

-- rand() rand(n)返回在范围0到1.0内的随机浮点值(可以使用数字n作为初始值)
select rand();
select rand(1); -- 随机数种子

-- truncate(n,d)保留数字n的d位小数并返回
select truncate(3.1415926,2);

-- least(x,y,...)  greatest(x,y,...)求最小值或最大值
select least(1,2,3,4,5,5,4,1),greatest(1,2,3,4,5,5,4,1);

-- mod(n,m)取模运算,返回n被m除的余数
select mod(10,3);
-- ceiling(n) floor(n)向上/向下取整函数
select ceil(3.14),floor(3.14);

-- round(n,d)返回n的四舍五入值,保留d位小数(d的默认值为0)
select round(3.54),round(3.15,2);

-- 查询每个部门的平均工资,保留两位小数
select deptno,round(avg(ifnull(sal,0)),2) from emp group by deptno; 



-- -----------------------------------
-- 第四类:高阶函数之排名函数的应用
--     1. row_number() over(...): 给排序过的表记录分配行号,从1开始的连续自然数
--     2. rank() over(...): 给排序过的表记录分配名词。相同的值名次一样,后续排名跳跃
--     3. dense_rank() over(...): 给排序过的表记录分配名词。相同的值名次一样,后续排名不跳跃

--  注意:over是一个开窗函数,用于给一个字段进行排序和分组的
-- -----------------------------------
select a.*,row_number() over(order By sal desc) rn from emp a;
select * from (select a.*,row_number() over(order By sal desc) rn from emp a) t where rn<4;
select * from (select a.*,row_number() over(order By sal desc) rn from emp a) t where rn>4 and rn<8;

-- 跳跃式排名
select a.*,rank() over(order By sal desc) rn from emp a;

-- 非跳跃式排名
select a.*,dense_rank() over(order By sal desc) rn from emp a;


-- 给每个部门进行排名  partition by [字段名] 用于指定分组字段
select a.*,row_number() over(partition by deptno order by sal desc) from emp a;
select a.*,rank() over(partition by deptno order by sal desc) from emp a;
select a.*,dense_rank() over(partition by deptno order by sal desc) from emp a;
 
 

你可能感兴趣的:(mysql,数据库)