码迷,mamicode.com
首页 > 数据库 > 详细

Oracle 经典查询例题

时间:2021-02-01 12:52:51      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:开始时间   丢失   oop   更新   sql语句   比赛   var   oracl   方法   

1 查询每门课程成绩都大于80分学生的学号
数据库 表 student
name score course
A 85 语文
A 75 数学
A 82 英语
B 75 语文
B 89 数学
B 79 英语
天使美眉90 语文
天使美眉100 数学
天使美眉100 英语

请找出每门课程都超过80分的那个人名字的SQL语句

SQL1:

select name from test.stu
group by name
having count(score) =sum(case when score>80 then 1 else 0 end )

SQL2:

select name from stu
group by name
having name not in (
select name from stu
where score <80)

SQL3:

select name from test.stu
group by name
having min(score)>=80


2.查询即选择课程001课程又选002的学号

student表:sno(学号),sname(姓名),sex(性别),dept(系)
course课程表:cno(课程号),课程名(cname)
sc选课表:sno,cno,grade(成绩)

sql语句:

select cno from sc a inner join (select * from sc where cno=(select cno from course where cname=‘001‘)) as b on a.cno>o=(select cno from course where cname=‘002‘)

思路如下:

采用内连接的方式

1.首先找到课程001在选课表的信息

select * from sc where cno=(select cno from course where cname=‘001‘)

这里 sql中 sc的cno 可以=另一张表(course)的cno

=的使用只可以在表中查询单个数据时使用

2.在找到选课002的信息

select*fromsc where cno=(select cno from course where cname=‘002‘)

  1. 内连接 注意取交集

select cno from sc a inner join (select * from sc where cno=(select cno from course where cname=‘001‘)) as b on a.cno>o=(select cno from course where cname=‘002‘)


3.关于shengfu_table表内容:

time state

2005-05-09 胜
2005-05-09 胜
2005-05-09 负
2005-05-09 负
2005-05-10 胜
2005-05-10 负
2005-05-10 负

如果要生成下列结果, 该如何写sql语句

胜 负
2005-05-09 2 2
2005-05-10 1 2

sql语句:

select time, sum(decode(status,‘胜‘,‘‘)) 胜 ,sum(decode(status,‘负‘,‘‘)) 负 from shengfu_table group by time;  

思路如下:

1.首先先进行分组 遇到多个相同行数据被整合 可优先考虑

2.统计胜的次数 负的次数 (注意:如果使用count的话不可以)

3.使用函数嵌套 sum(decode(status,‘胜’,‘’))胜 此方式


4.表中有A B C三列,用SQL语句实现:当A列大于B列时选择A列否则选择B列,当B列大于C列时选择B列否则选择C列。

sql语句:

select (case when a>b then a else b end),(case when b>c then b else c end) from tab4

思路如下:

1.使用了case when 这个方式

select(case when a>b then a else b end),(case when b>c then b else c end) from table;

  1. 有待商榷

decode(a>b,a,b),(b>c,b,c)from table;


  1. 一个日期判断的sql语句请取出tab5表中日期(SendTime字段)为当天的所有记录 (SendTime字段为datetime型,包含日期与时间)

    sql语句:

    select * from tab5 t where to_char(t.SendTime,‘yyyy-mm-dd‘)=to_char(sysdate,‘yyyy-mm-dd‘)

    思路如下

    1.需要用到函数sysdate (获取当天日期)

    select sysdate from dual;--20-12月-20 默认是这种格式,可以通过指定格式参数来显示指定格式的日期时间

    2.需要用到转换函数 to_char(dayaobj,fmt)

    把字符串形式的日期信息按照fmt格式进行转换

    -- 因为Oracle中date只显示日期,所以时间信息不显示
    select to_date(‘2020-12-20 15:33:44‘,‘yyyy-mm-dd hh24:mi:ss‘) from dual;-- 20-12月-20

    3.select * from tab5 where to_char(t.SendTime,‘yyy-mm-dd‘)=to_char(sysdate,‘yyy-mm-dd‘)

    补充:

    转换数据类型或格式
    to_date(datastr,fmt)
    把字符串形式的日期信息按照fmt格式进行转换

    -- 因为Oracle中date只显示日期,所以时间信息不显示
    select to_date(‘2020-12-20 15:33:44‘,‘yyyy-mm-dd hh24:mi:ss‘) from dual;-- 20-12月-20
    12
    

    to_char(dataobj,fmt)
    把日期对象显示为fmt指定的日期格式,还可以把数字转换为字符串形式

    -- 正常情况下sysdate不显示时间信息,并且日期的格式也不是按照年月日展示
    select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss‘) from dual;-- 2020-12-20 15:50:11
    12
    

    to_number(numberStr,fmt)
    把字符形式的数字按照一定的格式转换为数字

    select to_number(‘00123‘) from dual;-- 123
    select to_number(‘12345.678‘, ‘99999.999‘) from dual;-- 12345.678,参数1和2要对应,参数2可以比参数1位
    

6.有一张表,里面有3个字段:语文,数学,英语。其中有3条记录分别表示语文70分,数学80分,英语58分,请用一条sql语句查询出这三条记录并按以下条件显示出来
大于或等于80表示优秀,大于或等于60表示及格,小于60分表示不及格。
显示格式:
语文 数学 英语
及格 优秀 不及格

sql语句:

1.case when方法

select
(case when语文>=80 then ‘优秀‘ when语文>60 then ‘及格‘ else ‘不及格‘ end) as 语文,
(case when 数学>=80 then ‘优秀‘ when数学>60 then ‘及格‘ else ‘不及格‘ end) as数学,
(case when英语>=80 then ‘优秀‘ when英语>60 then ‘及格‘ else ‘不及格‘ end) as 英语
from tab5

2.decode方法

select decode(sign(语文-80),1,‘及格‘,0,‘及格‘-1,‘不及格’) as 语文,

? decode(sign(数学-60),1,‘及格‘,0,‘及格‘,-1,‘不及格’) as 语文,

? decode(sign(英语-60),1,‘及格‘,0,‘及格’,-1,‘不及格‘) as 语文 from tab6;


7.请用一个sql语句得出结果
从table1,table2中取出如table3所列格式数据

table1

月份mon 部门dep 业绩yj
-------------------------------
一月份 01 10
一月份 02 10
一月份 03 5
二月份 02 8
二月份 04 9
三月份 03 8

table2

部门dep 部门名称depname
--------------------------------
01 国内业务一部
02 国内业务二部
03 国内业务三部
04 国际业务部

table3 (result)

部门dep 一月份 二月份 三月份
---------------------------------------------------
01 10 null null
02 10 8 null
03 5 null 8
04 null 9 null
-------------------------------------------------------

sql语句:

select t.dep,
(select yj from tab6 where mon=‘一月份‘ and dep=t.dep) 一月份,
(select yj from tab6 where mon=‘二月份‘ and dep=t.dep) 二月份,
(select yj from tab6 where mon=‘三月份‘ and dep=t.dep) 三月份
from tab7 t

2.求总销售额

select
sum(case when t1.mon=‘一月份‘ then t1.yj else 0 end) 一月份,
sum(case when t1.mon=‘二月份‘ then t1.yj else 0 end) 二月份,
sum(case when t1.mon=‘三月份‘ then t1.yj else 0 end) 三月份
from tab7 t,tab6 t1 where t.dep=t1.dep;


8.一个表中的Id有多个记录,把所有这个id的记录查出来,并显示共有多少条记录数。

select Id,count(*) from tab8 group by Id having count(1)>1;

注意:

having 用法与WHERE用法类似,但有三点不同
1、HAVING只用于GROUP BY(分组统计语句),
2、WHERE 是用于在初始表中筛选查询,HAVING用于在WHERE和GROUP BY 结果中查询。
3、HAVING可以使用聚合函数,面WHERE 不能。

统计用户表中姓名为“李”(WHERE子句定义),出现多于一次(having 用聚合函数COUNT(1)定义)的人的用户
SELECT USERCODE,username=max(username),次数=count(1) from usertable where username like ‘李%‘ group by usercode having count(1)>1


  1. 一个叫department的表,里面只有一个字段name,一共有4条纪录,分别是a,b,c,d,对应四个球对,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合.

    sql语句:

    select a.name,b.name from department a department b where a.name!=b.name and b.rowid>a.rowid

    注意:

    rownum 不可以在内表中使用 比如 a.rownum 不可以

    rownum是临时编号

    关于rownum 与row_number() over 我将详细讲解 此处省略


10.怎么把这样一个表儿
year month amount
1991 1 1.1
1991 2 1.2
1991 3 1.3
1991 4 1.4
1992 1 2.1
1992 2 2.2
1992 3 2.3
1992 4 2.4
查成这样一个结果
year m1 m2 m3 m4
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4

  sql语句:

  select year,

  ?          (select  a.amount from tab10 awhere a.month=1 and t.year = a.year)m1,

  ?          (select b.amount from tab10 b where b.month=2 and b.year=t.year)m2,

  ?          (select c.amount from tab10 c where c.month=3 and c.year=t.year )m3,

  ?          (select d.amount from tab10 d where d.month=4 and d.year=t.year)m4

  from tab10 t group by t.year;

  -----

11.拷贝表(拷贝数据,源表名:a 目标表名:b)

  SQL: insert into b(a, b, c) select d,e,f from b;

  create table test as select * from dept; --从已知表复制数据和结构 

  create table test as select * from dept where 1=2; --从已知表复制结构但不包括数据 

  ------

?

12.两张关联表,删除主表中已经在副表中没有的信息

  sql语句:

   delete from f12 a where a.fid not in(select id from z12);

  补充:

  1. in和exists

     in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不准确的。

     如果查询的两个表大小相当,那么用in和exists差别不大。

     如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:

     例如:表A(小表),表B(大表)1:select * from A where cc in (select cc from B)

     效率低,用到了A表上cc列的索引;select * from A where exists(select cc from B where cc=A.cc)

     效率高,用到了B表上cc列的索引。

     相反的2:select * from B where cc in (select cc from A)

     效率高,用到了B表上cc列的索引;select * from B where exists(select cc from A where cc=B.cc)

     效率低,用到了A表上cc列的索引。 

  2. not in 和not exists

      如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

  3. not in 逻辑上不完全等同于not exists,如果你误用了not in,小心你的程序存在致命的BUG

13.有两个表tab12和tab13,均有key和value两个字段,如果tab13的key在tab12中也有,就把tab13的value换为tab12中对应的value

sql语句:

update tab13 set value=(select value from tab12 where tab12.key=tab13.key)

思路如下:

  1. update table set 字段=() 更新语句

  2. ()内可以书写sql语句 注意查询的列要与更新的列对应

  3. 更精确:

    update b set b.value=(select a.value from a where a.key=b.key) where b.id in(select b.id from b,a where b.key=a.key);


  1. 原表:
    courseid coursename score
    -------------------------------------
    1 java 70
    2 oracle 90
    3 xml 40
    4 jsp 30
    5 servlet 80
    -------------------------------------
    为了便于阅读,查询此表后的结果显式如下(及格分数为60):
    courseid coursename score mark
    ---------------------------------------------------
    1 java 70 pass
    2 oracle 90 pass
    3 xml 40 fail
    4 jsp 30 fail
    5 servlet 80 pass
    ---------------------------------------------------

    sql语句:

    select t14.*,decode(sign(score-60),1,‘及格‘,0,‘及格‘,-1,‘不及格‘) mark from tab14 t14;


  2. 表15
    a1 a2
    1 a
    1 b
    2 x
    2 y
    2 z
    用select能选成以下结果吗?

? 1 ab
2 xyz


16.题为
有两个表, t1, t2,
Table t1:

SELLER | NON_SELLER
----- -----
A B
A C
A D
B A
B C
B D
C A
C B
C D
D A
D B
D C

Table t2:

SELLER | BAL
------ --------
A 100
B 200
C 300
D 400
要求用SELECT 语句列出如下结果:------如A的SUM(BAL)为B,C,D的和,B的SUM(BAL)为A,C,D的和.......
且用的方法不要增加数据库负担,如用临时表等

sql语句:

SELECT SELLER,a.total-t.BAL FROM t,(SELECT SUM(BAL) total FROM t)a;

17.查询某字段值为null、0、空字符串sql

sql语句:

SELECT * FROM student WHERE ISNULL(value or value=null); --null,empty,0;

注:有时候遇到表结构比较特殊会需要查询某字段值为 null ,0,empty。


  1. 学生表 如下:
    自动编号 学号 姓名 课程编号 课程名称 分数
    1 2005001 张三 0001 数学 69
    2 2005002 李四 0001 数学 89
    3 2005001 张三 0001 数学 69
    删除除了自动编号不同, 其他都相同的学生冗余信息

sql语句:

A: delete tablename where 自动编号 not in(select min( 自动 编号) from tablename group by学号, 姓名, 课程编号, 课程名称, 分数)


19.说明:日程安排提前五分钟提醒

sql语句:

select * from 日程安排 where datediff(‘minute‘,f 开始时间,getdate())>5


20.高级面试题:

create table testtable1
(
id int IDENTITY,
department varchar(12)
)

select * from testtable1
insert into testtable1 values(‘设计‘)
insert into testtable1 values(‘市场‘)
insert into testtable1 values(‘售后‘)

结果
id department
1 设计
2 市场
3 售后

create table testtable2
(
id int IDENTITY,
dptID int,
name varchar(12)
)
insert into testtable2 values(1,‘张三‘)
insert into testtable2 values(1,‘李四‘)
insert into testtable2 values(2,‘王五‘)
insert into testtable2 values(3,‘彭六‘)
insert into testtable2 values(4,‘陈七‘)

用一条SQL语句,怎么显示如下结果
id dptID department name
1 1 设计 张三
2 1 设计 李四
3 2 市场 王五
4 3 售后 彭六
5 4 黑人 陈七

sql语句:

SELECT testtable2.* , ISNULL(department,‘黑人‘)
FROM testtable1 right join testtable2 on testtable2.dptID = testtable1.ID

思路如下:

1.采用右链接的方式 因为以第二张表为主表 ,并且如果不适用的话,采用其他限制因素,比如where t2.dptID=t1.id 那么没有部门的人就会数据丢失。

2.采用判空的思维 比如没有部门 那么用语句 ISNULL(department,‘黑人‘)这样处理


Oracle 经典查询例题

标签:开始时间   丢失   oop   更新   sql语句   比赛   var   oracl   方法   

原文地址:https://www.cnblogs.com/yk2763691852/p/14352892.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!