只用经典4张表,可以练习到所有查询语句。
-- 创建部门表
-- 字段:部门编号、部门名、地点
create table DEPT(
DEPTNO int(2) not null,
DNAME varchar(14),
LOC varchar(13)
);
alter table DEPT add constraint PK_DEPT primary key (DEPTNO);
-- 创建员工表
-- 字段:员工编号(主键)、姓名、工作、上级编号(与同表的empno自关联)、入职日期、工资、津贴、部门编号
create table EMP(
EMPNO int(4) primary key,
ENAME varchar(10),
JOB varchar(9),
MGR int(4),
HIREDATE DATE,
SAL double(7,2),
COMM double(7,2),
DEPTNO int(2)
);
-- 外键约束:EMP表的DEPTNO与DEPT表的主键DEPTNO关联
alter table EMP add constraint FK_DEPTNO foreign key (DEPTNO) references DEPT (DEPTNO);
-- 创建工资等级表
-- 字段:工资等级(主键)、最低工资、最高工资
create table SALGRADE(
GRADE int primary key,
LOSAL double(7,2),
HISAL double(7,2)
);
-- 创建奖金表
-- 字段:姓名、工作、工资、津贴
create table BONUS(
ENAME varchar(10),
JOB varchar(9),
SAL double(7,2),
COMM double(7,2)
);
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');
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);
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);
select * from emp;
select empno,ename,sal from emp;
使用where子句
select * from emp where sal>2000;
select empno,ename,job,mgr from emp where sal>2000;
select empno as '员工编号',ename as '姓名' from emp;
-- as、‘’ 可省略
select empno 员工编号,ename 姓名 from emp;
-- 别名里有特殊符号如空格 ''不可以省略
select empno as '员工 编号',ename as '姓名' from emp;
select empno,ename,sal,sal+1000 涨薪后,deptno from emp where sal<2500;
select empno,ename,sal,comm,sal+comm from emp;
-- 如果有null 加出来为空 但有0加出来是正确的 解决方法见下方 10.2)单行函数-(4)流程函数-if相关-第三条sql语句
select distinct job from emp;
select distinct job,deptno from emp;
-- distinct对后面所有列的组合 去重 而不是单独对某一列去重
-- 比如10的manager 20的manager
-- 默认按照升序排列 asc升序 decs降序
select * from emp order by sal;
select * from emp order by sal desc;
-- 可以2个排序组合:在工资升序的情况下,工资相同时,deptno按照降序排列
select * from emp order by sal asc, deptno desc;
将过滤条件放在where子句后面,过滤出符合条件的数据, 可以按数值、字符串、日期类型筛选。
select * from emp where deptno=10;
select * from emp where job = 'CLERK';
select * from emp where job = 'clerk';
select * from emp where binary job='CLERK';
select * from emp where hiredate < '1981-12-25';
select * from emp where sal>1500 and sal<3000;
select * from emp where sal>1500 && sal<3000;
select * from emp where sal between 1500 and 3000;
select * from emp where deptno=10 or deptno=20;
select * from emp where deptno=10 || deptno=20;
select * from emp where deptno in (10,20);
select * from emp where job in ('MANAGER','CLERK','ANALYZE');
优先级:and优先于or,为了增加可读性,使用小括号() 。
select * from emp where (job = 'SALESMAN' or job='CLERK' )and sal>=1500;
select * from emp where job = 'SALESMAN' or (job='CLERK' and sal>=1500);
select * from emp where ename like '%A%';
-- %代表任意多个字符
select * from emp where ename like '_A%';
-- _代表任意一个字符
select * from emp where ename like '__A%';
select * from emp where comm is null;
select * from emp where comm is not null;
多行函数是指对一组数据进行运算,针对这一组数据(多行记录)只返回一个结果,也称为分组函数。 多行函数自动忽略null值。最大值max()、最小值min()、计数count()针对所有类型;求和sum()、平均值avg() 只针对数值型类型有效。多行函数只有这5个。
select max(sal), min(sal), count(sal), sum(sal), avg(sal) from emp;
select max(comm), min(comm), count(comm), sum(comm), avg(comm) from emp;
select count(*) from emp;
单行函数是指对每一条记录输入值进行计算,并得到相应的计算结果,然后返回给用户,也就是说,每条记录作为一个输入参数,经过函数计算得到每条记录的计算结果。
select ename,length(ename),substring(ename,2,3) from emp;
-- substring字符串截取,从字符下标为2开始,截取长度3(下标从1开始)
-- 未从表中查询:末尾可以加上 from dual,代表一个伪表,也可以省略。
select abs(-5) 绝对值,ceil(5.3) 向上取整,floor(5.9)向下取整,round(3.14)四舍五入;
select ceil(sal) from emp;
select 10/3,10%3,mod(10,3);
-- 除以 取模 取模
select curdate(),curtime();
-- curdate()年月日 curtime()时分秒
select now(),sysdate();
-- now(),sysdate() 年月日时分秒
select now(),sysdate(),sleep(3),now(),sysdate();
-- now()也可以用于插入数据 例如insert int emp values(9999,'ss','SALESMAN',7698,now(),1000,null,30);
-- now()插入数据的时候还要参照表的结构
if相关:
select empno, ename, sal, if(sal>=2500,'高薪','一般') from emp;
select empno, ename, sal, if(sal>=2500,'高薪','一般') as '薪资等级'from emp;
select empno, ename, sal, comm, sal+ifnull(comm,0) from emp;
select nullif(1,1),nullif(1,2);
-- 如果value1等于value2,则返回null,否则返回value1
case相关:
select empno, ename, job,
case job
when 'CLERK' then '店员'
when 'SALESMAN' then '销售员'
when 'MANAGER' then '经理'
else '其他'
end as '岗位' ,
sal from emp;
select empno, ename, sal,
case
when sal<= 1000 then 'C'
when sal<= 2000 then 'B'
when sal<= 3000 then 'A'
else 'H'
end as '工资等级'
from emp;
select database(),user(),version();
select deptno, avg(sal) from emp group by deptno;
select deptno, avg(sal) from emp group by deptno order by deptno desc;
select job, avg(sal) from emp group by job;
select job, lower(job),avg(sal) from emp group by job;
select deptno, avg(sal) as 平均工资 from emp group by deptno having avg(sal)>2000;
-- 分组以后进行二次筛选 having
-- 方法1
select job, avg(sal) from emp where job != 'MANAGER' group by job;
-- 方法2:
select job, avg(sal) from emp group by job having job != 'MANAGER';
where:分组前过滤;having:分组后过滤
select语句书写顺序:(顺序固定,不可改变)
select column, group_function(column)
from table
[where condition]
[group by group_by_expression]
[having group_condition]
[order by column];
select语句的执行顺序:
from-where-group by-select -having-order by
列出工资最小值小于2000的职位
select job, min(sal) from emp group by job having min(sal)<2000 ;
列出平均工资大于1200的部门和工作搭配组合
select deptno, avg(sal) from emp group by deptno, job having avg(sal)>1200;
统计人数小于4的部门的平均工资
select deptno, count(*), avg(sal) from emp group by deptno having count(*)<4;
统计各部门的最高工资,排除最高工资小于3000的部门
select deptno, max(sal) from emp group by deptno having max(sal)>=3000;