SQL基础练习题以及自我知识部分整理:

别等时光非礼了梦想. 提交于 2019-12-23 12:16:19

数据库总结:

行列转换:

case 字段
    when1 then 结果
    when2 then 结果2
    ...
    else 默认结果
end

在这里插入图片描述

列转行
在这里插入图片描述

select 姓名 ,
sum(case 课程 when 语文  then 分数 else 0 end) as 语文,
sum(case 课程 when 数学  then 分数 else 0 end) as 数学,
sum(case 课程 when 英语  then 分数 else 0 end) as 英语,
from scores group by 姓名

select 日期,
sum(case 结果 whenthen res) as 胜,
sum(case 结果 whenthen res) asfromselect 日期,结果,count(*) res from A group by 日期,结果)t
group by 日期



逆向 行转列

select 姓名,
 '语文' as 课程,
 语文 as 分数
 from scores2 
 union all
  select 姓名,
 '数学' as 课程,
 数学 as 分数
 from scores2 
 union all
  select 姓名,
 '物理' as 课程,
 物理 as 分数
 from scores2 
 order by 姓名 desc

需求:根据用户的id来查找用户关注的人发布的动态

<select id="selectdynamibycuser" parameterType="java.lang.Integer"
	resultType="com.myplay.model.dynamicAndUser">
	select
	t.id,t.t.title,t.createtime,t.uid,t.content,t.id_u,t.name,t.sex,
	t.signature,t.photourl,t.phone from
	(select d.id,d.title,d.createtime,
	d.uid,d.content,u.id id_u,u.name,
	u.sex,u.signature,u.photourl,u.phone from dynamic d,user u
	where d.uid=u.id)
	t,follow f where f.from_uid=#{to_id}
	and f.to_uid =t.uid
</select>

–1.查询平均工资最高的部门的部门编号、部门名称和该部门的平均工资

select * from (  
select t2.deptno,dname,avg(sal) avg_sal from emp t1,dept t2 where t1.deptno=t2.deptno group by t2.deptno,dname
) where avg_sal=(select max(avg(sal)) from emp group by deptno)

–2.查询所有员工的年薪、所在部门的名称,查询结果按年薪从低往高排序

select t1.ename,t1.sal*12+nvl(comm,0) s,t2.dname from emp t1,dept t2
where t1.deptno=t2.deptno order by s

–3.查询每种工作的最低工资,以及领取该工资的员工姓名,
–查询结果显示工作名称、最低工资、领取该工资的员工姓名;

select t2.job,t2.min_sal, t1.ename from emp t1,
(select job, min(sal) min_sal from emp group by job) t2 
where t1.job=t2.job and t1.sal=t2.min_sal

–4.查询出管理员工人数最多的人的名字和他管理的人的名字

select t.ename,wm_concat(e.ename) from emp e ,(
select empno,ename from emp t1,(
select * from (
select mgr ,count(*) num from emp group by mgr order by num desc
) where rownum=1) t2 where t1.empno=t2.mgr
) t where e.mgr=t.empno group by t.ename

select t3.ename,t4.ename from emp t4,
(select t1.ename,t1.empno from emp t1,
(select mgr,count(*) cnum from emp group by mgr order by cnum desc) t2
where t2.mgr=t1.empno and rownum=1) t3
where t4.mgr=t3.empno;

–5.查询所有员工的编号、姓名,及其上级领导的编号、姓名。显示结果按领导的年薪降序排列

select t1.ename,t1.empno,t2.ename mgr_name,t2.empno mgr_no,y_sal from emp t1,
(select ename,empno,sal*12+nvl(comm,0) y_sal from emp) t2
where t2.empno=t1.mgr order by y_sal desc

–6.查询所有领取奖金和不领取奖金的员工人数、平均工资:
–查询结果的列名分别为:人数、平均工资:第一行为有奖金的员工,第二行为没有奖金的员工

select count(nvl2(comm,1,0)) num,avg(sal) from emp group by nvl2(comm,1,0)

–7.查询工资不超过2500的人数最多的部门名称和该部门工资不超过2500的员工的员工人数

select * from(
select dept.dname,t1.num from dept,
(select count(*)as num,deptno from emp where sal<2500 group by deptno)t1
where dept.deptno=t1.deptno order by num desc) where rownum =1 

–8.查询受雇日期早于其直接上级的所有员工的编号,姓名,部门名称

select e.empno,e.ename,d.dname from emp e,emp m,dept d
where e.mgr=m.empno and e.hiredate<m.hiredate and e.deptno=d.deptno

–9.查询至少有4个员工的部门的部门名称

select *from (select t1.deptno,t2.dname,count(*) numb from emp t1,dept t2 where t1.deptno=t2.deptno
group by t1.deptno,t2.dname )t3 where t3.numb>=4

–10.查询工资比“SMITH”高s的员工的基本信息

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

–11.查询部门名称中带’S’字符的部门的员工的工资总和部门人数,显示结果为部门名称,部门员工的工资总和,部门人数

select dname,sum(sal),count(*) from emp e ,dept d where e.deptno = d.deptno and dname like '%S%' group 
by dname

–12.查询所有从事"CLERK"工作的雇员所在部门的部门名称、部门里的人数

select dname,count(*) from emp t1,dept t2 where t1.deptno = t2.deptno and
job = 'CLERK' group by dname

–13.查询雇员领导的基本信息,要求领导的薪水要超过3000

select distinct m.* from emp e,emp m where e.mgr=m.empno and m.sal>3000

–14.查询在"sales"部门( 销售部)工作的员工的姓名

select ename from emp natural join dept where dname='SALES'

–15.查询工资高于30号部门的所有员工的工资的员工姓名、工资及部门名称

select ename,sal,dname from emp join dept on emp.deptno = dept.deptno
where sal>all(select sal from emp where deptno = 30)

–16.查询所有部门的详细信息(部门编号、部门名称)和部门人数

–16.查询所有部门的详细信息(部门编号、部门名称)和部门人数

select d.deptno,d.dname,count(*) from emp e,dept d where e.deptno=d.deptno 
group by d.deptno,d.dname

–17.显示每个部门中每个岗位的平均工资、每个部门的平均工资、每个岗位的平均工资

select deptno,job ,avg(sal) dep_job_avg from emp group by deptno,job

select job ,avg(sal) job_avg from emp group by job

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

select dep_job_avg,job_avg,dep_avg from 
(select deptno,job ,avg(sal) dep_job_avg from emp group by deptno,job) t1
left outer join 
(select job ,avg(sal) job_avg from emp group by job) t2
on t1.job = t2.job
left outer join
(select deptno ,avg(sal) dep_avg from emp group by deptno) t3
on t1.deptno = t3.deptno

–18.显示与"BL AKE"同部门的所有员工的基本信息,但不显示"BL AKE"的基本信息

select deptno from emp where ename='BLAKE'
select * from emp where deptno=(select deptno from emp where ename='BLAKE') and ename <> 'BLAKE'

–19.查询出"KING”所在部门的部门编号、部门名称以及该部门里的员工人数

SELECT D.DEPTNO,DNAME,COUNT(*) FROM EMP E,DEPT D WHERE E.DEPTNO=D.DEPTNO 
AND D.DEPTNO=(SELECT DEPTNO FROM EMP WHERE ENAME='KING') GROUP BY DNAME,D.DEPTNO

–20.查询出"WARD"所在部门的工作年限最大的员工的姓名

select ename from(
select * from emp where deptno=(select deptno from emp where ename='WARD')order by hiredate
)where rownum=1

–21.查询出没有下属的员工的姓名及他的职位

select * from emp where empno
 not in(select mgr from emp where mgr is not null group by mgr)

–22.查询出员工姓名以A开头的人数最多的部门的部门名称

select dname from dept where deptno=(
select deptno from (
select deptno,count(*) num from emp where ename like 'A%' group by deptno 
order by num desc ) where rownum=1)

–23.查询出SMITH所在部门的部门名称、部门工资的平均值(注意平均值保留两位小数)

select t1.dname ,t2.avg_sal from dept t1,(
select deptno ,round(avg(sal),2) avg_sal from emp where deptno=
(select deptno from emp where ename like 'SMITH') group by deptno) t2
where t1.deptno=t2.deptno

Ø 需求3:查询员工的姓名、薪水、部门编号,先按部门编号升序、部门编号相同的按姓名降序

       select ename,sal,deptno from emp order by deptno asc,ename desc 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e52rTdnl-1576551400651)(C:\Users\41765\Desktop\面试\数据库\fun.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YdaXu6M4-1576551400652)(C:\Users\41765\Desktop\面试\数据库\funex.png)]

Ø 需求1:获得系统当前时间

select sysdate from dual;

Ø 需求2:想知道雇员表中,部门编号为60的雇员,截止到今天共工作了多少周,则可以使用如下的SQL语句

select ename ,round((sysdate-hiredate)/7) as weeks from emp where deptno = 60

Ø 需求3:下周三是几号?

​ 使用函数 NEXT_DAY(date,char)

​ date指定日期,char周几,计算指定日期的下一个周几是几号

​ 注意:1表示周日2表示周1以此类推

select next_day(sysdate,2) from dual;

to_char

功能:将指定参数转换成字符

Ø 需求1:转换货币格式

   select to_char(sal,‘$99,999.9999)  as工资 from emp;

​ 9表示一位数字,如果该位没有数字则不显示但小数点后的数字必须显示

Ø 需求2:格式化日期格式

select to_char(hiredate,'YYYY-MM-DD HH:MI:SS') from emp;

select to_char(sysdate,'YYYY-MM-DD HH:MI:SS') from dual;

select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') from dual;

​ 注意:

​ oracle日期大小写都一样,java大小写不一样

​ 分和java不一样 用MI表示 java用mm表示

​ oracle 24小时制 用HH24表示 java用HH表示

to_date(参数)

​ 功能:将指定参数转换成date类型

Ø 需求:查询入职日期在‘1981-2-20 12:34:56’之后的员工的姓名和入职日期

select ename,hiredate from emp where hiredate>to_date('1981-2-20 12:34:56','YYYY-MM-DD HH24:MI:SS');

to_number(参数)

​ 功能:将指定参数转换成number类型

Ø 需求:查询薪水大于$1,250.00元的员工姓名和薪水

    select ename ,sal from emp where sal>to_number('$1,250.00','$9,999.99');

NVL(参数1,参数2)

Ø 求真正的年薪(带年终奖),使用如下语句会发生错误

  select ename,sal*12+comm as annual_sal from emp

原因是null和任何数参与四则运算都返回null

nvl(comm,0) 如果第一个参数为null,则返回第二个参数(0),如果第一个参数不为null,则函数返回第一个参数本身

  select ename,sal*12+nvl(comm,0) as annual_sal from emp

NVL2(参数1,参数2,参数3)

​ 功能:参数1不是null 返回参数2 参数1是null 返回参数3

Ø 需求:有年终奖comm的员工过节费是月薪的30%,没有年终奖的员工过节费是月薪的50%

  select ename,nvl2(comm,sal*0.3,sal*0.5) as 过节费 from emp

COALESCE函数

COALESCE函数比NVL函数功能强大,它能够接受多个交替的值,其语法形式如下

COALESCE (expr1, expr2, … exprn)

作用:如果表达式1为非空,则返回表达式1的值;如果表达式1为空但表达式2不为空则返回表达式2的值,依次类推,如果前面的表达式都为空,则返回表达式n的值

需求: 列出至少有一个员工的所有部门的部门名称

select distinct dname from emp t1,dept t2 where t1.deptno = t2.deptno  

select dname from dept t1 where exists(select * from emp t2 where t1.deptno = t2.deptno) 当外表很小而内表很大时用 exists效率会高很多

exists 和 in 有什么 区别?
如果 in 里面的结果集非常大 效率就低,我们可以用exist替换它

总查询 里面的组函数一定要有别名

需求:创建一个视图, 名称为EMPVU10, 使其包含EMP表中部门为10的职员的详细信息

CREATE VIEW 	empvu10
    AS 
    SELECT	empno, ename, job
    FROM  emp
    WHERE	deptno = 10;

需求:给雇员表的job一列建立索引

create index emp_job_index on emp(job)

Oordr by 列明
降序desc
升序:asc 默认

如果排序有多个条件,用“,”分开

字符串下标从1开始

多表联立:
等值连接,where子句 两表之间用‘,’条件where
on子句 两表之间用 inner join 条件用 on
using 子句的列部分不能有限定词;

非等值连接,
笛卡尔乘积

左外连接:保证左表的数据全部显示,右表用null填充。

右外连接:right join

全连接:full

子关联:

where 分组之前的过滤 having 分组后的过滤

exists 和 in的区别: in 操作的结果集如果非常大,效率就很慢,就用exists替换

子查询:也叫嵌套查询 多个select嵌套出现
第一次查询的结果作为第二次查询的条件,

多行子查询: in any all

注意如果别名本身带有空格,需要用””括起来,例如年薪字段想显示成annual sal,语句如下
Java中字符串连接是 + 号 ,oracle中字符串连接是 || 号
如果字符串中本身就有 ’,想显示这个单引号,需要使用两个单引号进行转义,即 ’’代表 ’

需求:查一下一共有几个工种
select distinct job from emp

注意:<>表示不等于,也可以用!=表示

distinct修饰两个或两个以上字段 如果distinct修饰两个字段,代表两个字段组合起来不能重复

使用in代替多个or

使用like关键字,支持条件的模糊查询
横线_代表一个字母 %代表0个或多个字母
要想查带%的字符串 需要用到转义字符%

asc表示升序 desc表示降序

is null 判断一列是否为空

Round(参数1,[参数2])
功能:四舍五入,参数2可选,参数2表示保留几位小数

Trunc(参数1,[参数2])
功能:截断数字(直接忽略),参数2表示截断到的小数位,如果参数2忽略则默认为0

如果分组了,select后面的字段要么是分组的条件,要么是组函数

in(1,2,3) 等于其中的任何一个都可以
=any等于其中的任何一个都可以
<any(1,2,3) 小于子查询的最大值
<all(1,2,3) 小于子查询的最小值

any(1,2,3) 大于子查询的最小值
all(1,2,3) 大于子查询的最大值

union:并集-------------A和B的并集,去掉重复行
union all:并集----------A和B的并集,不去掉重复行
minus:差集-------------A中的结果减去B中的结果
intersect:交集----------A和B的交集

– 必须以字母开始
– 必须是1到30 个字符长度
– 只能包含字母、数字、下划线“_”、美元符“$”和井号“#”
– 不能使用Oracle的关键字
– 同一个用户所拥有的对象之间不能重名

约束:NOt null 非空约束 只能设置在字段上
Unique 唯一约束
primarykey 主键约束
foreign key 外键约束 --外键指向主表的主键或者唯一键
check 检查约束
字段级别的约束

create table tb_student(
	sid varchar(10) primary key,
  sname varchar(32) not null
)

select * from tb_student 
create table tb_teacher(
	tid varchar(10) primary key,
  tname varchar(32) not null
)

select * from tb_teacher 
create table tb_course(
	cid varchar(10) primary key,
  cname varchar(32) not null,
  tid varchar(10) not null,
  years varchar(6) not null,
  constraint fk_tb_teacher_tid foreign key(tid) references tb_teacher(tid) 
)

select * from tb_score 
create table tb_score(
	sid varchar(10),
  cid varchar(10),
  score int not null,
  years varchar(6),
  primary key(sid,cid),
  foreign key(sid) references tb_student(sid),
  foreign key(cid) references tb_course(cid)
)

select sc.years,s.sname,c.cname,t.tname,sc.score from tb_teacher t,tb_course c,tb_score sc ,tb_student s
where t.tid=c.tid and c.cid=sc.cid and sc.sid=s.sid and s.sname='张三' 
order by sc.years desc ,c.cname 

select sc.years ,c.cname,avg(sc.score) from tb_teacher t,tb_course c,tb_score sc 
where t.tid=c.tid and c.cid=sc.cid and t.tname='李老师' group by sc.years 

SQL编写顺序

​ select 显示列

​ from 表

​ where 条件

​ group by 分组条件

​ having 对分组进行过滤

foreign key(sid) references tb_student(sid),
foreign key(cid) references tb_course(cid)
)

select sc.years,s.sname,c.cname,t.tname,sc.score from tb_teacher t,tb_course c,tb_score sc ,tb_student s
where t.tid=c.tid and c.cid=sc.cid and sc.sid=s.sid and s.sname=‘张三’
order by sc.years desc ,c.cname

select sc.years ,c.cname,avg(sc.score) from tb_teacher t,tb_course c,tb_score sc
where t.tid=c.tid and c.cid=sc.cid and t.tname=‘李老师’ group by sc.years


SQL编写顺序

​       select 显示列

​       from 表

​       where 条件

​       group by 分组条件

​       having  对分组进行过滤

​       order by 排序条件 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!