设为首页 收藏本站
查看: 795|回复: 0

[经验分享] sql语句的复杂操作

[复制链接]

尚未签到

发表于 2016-11-11 07:07:49 | 显示全部楼层 |阅读模式
oracle202






sql语句的复杂操作



SQL语句的执行顺序:

select from where 的执行顺序:from(选择表) where(选择行,横向过滤) select(选择列,竖向过滤)

select from where having order by group by 的执行顺序是:

fromwheregroup byhavingselectorder
by








create table student(snonumber(6) ,birthday date,snamevarchar2(10));

insert into student values(1,'81/1/11' ,'张三');

insert into student values(2,'82/3/10', '李四');

insert into student values(3,'83/1/06', '王五');

insert into student values(4,’83/1/26', '赵六');



create table address(snonumber(6) ,zzvarchar2(10));

insert into address values(1, '郑州');

insert into address values(2, '开封');

insert into address values(3, '洛阳');

insert into address values(4, '郑州');







要求:求出地址为郑州的,而且是学号最大的学生姓名:

SQL> select s.sname from student s where s.sno=(select max(a.sno) from address a where a.zz='郑州');

SNAME

----------

赵六


SQL>




SQL> create table temp as select s.sno,s.sname,a.zz from student s inner join address a on s.sno = a.sno where a.zz='郑州';

Table created


SQL> select t1.sno,t1.sname from temp t1 inner join temp t2on t1.sno > t2.sno; //使用自连接来比较大小

SNO SNAME

------- ----------

4 赵六


SQL>




select case when的使用
  The syntax for simpleCASEstatements is:

CASE expr WHEN comparison_expr THEN return_expr
[, WHEN comparison_expr THEN return_expr]... [ELSE else_expr] END





create table成绩(snonumber, km varchar2(10), scorenumber,gradechar(6));

insert into成绩values(1, '语文', 65,null);

insert into成绩values(2, '数学', 76,null);

insert into成绩values(3, '英语', 86,null);

insert into成绩values(4, '语文', 94,null);






要求:把每个学生的grade列,用相应的等级来更新


分为几部分来分析:

  1.如何得出不同成绩代表的不同的级别;




(select sno,

         case
          when g1.score >= 90 then '优秀'
           when g1.score >=80 then '良好'
            when g1.score >=70 then '中等'
             when g1.score >=60 then '及格'
              else '不及格'
               end grade

from 成绩 g1)

  2. 如何更新每一列;




update 成绩 g2 set g2.grade=(

select a.grade from

(select sno,

case

when g1.score >= 90 then '优秀'

when g1.score >=80 then '良好'

when g1.score >=70 then '中等'

when g1.score >=60 then '及格'

else '不及格'

end grade

from 成绩 g1) a

where a.sno =g2.sno);


注意:在雨中子查询可以使用父查询中表的属性,但是父类不能使用自类查询中表的属性





复杂更新语句的使用



表T1里有a,b,c...N个字段表T2里有a,b,c三个字段

然后想在T1中"c"与表T2中"c"相同的情况下从表T2中将a,b覆盖表T1中的a,b怎么做 ?



create table T1(aint,bint,cint,dint,eint);

create table T2(aint,bint,cint);



insert into T1 values(1,2,3,4,5);

insert into T1 values(10,20,3,4,5);

insert into T1 values(10,20,4, 40,50);

insert into T2 values( -1, -1 , 3);

insert into T2 values( -2, -2, 4);







分析:首先要明白一点就是更新的操作是针对一行一行的来进行的


第一步:确定需要更新的行:

  update t1 set t1.a = ? , t1.b = ? where t1.c in (select t2.c from t2);

第二步:确定更新需要的值

SQL> update t1 set t1.a =(select t2.a from t2 where t2.c = t1.c) ,

     t1.b=(select t2.b from t2 where t2.c = t1.c)

     where t1.c in (select t2.c from t2);




3 rows updated









分析函数



分析函数用于计算完成聚集的累计排名、序号等

分析函数为每组记录返回多个行

以下三个分析函数用于计算一个行在一组有序行中的排位,序号从1开始

ROW_NUMBER返回连续的排序,不论值是否相等

RANK具有相等值的行排序相同,序数随后跳跃

DENSE_RANK具有相等值的行排序相同,序号是连续的








DECODE函数的使用if then else的逻辑


q在逻辑编程中,经常用到If – Then –Else进行逻辑判断。在DECODE的语法中,实际上就是这样的逻辑处理


过程。它的语法如下:


qDECODE(value, if1, then1, if2,then2, if3,then3, . . . else )


qValue代表某个表的任何类型的任意列或一个通过计算所得的任何结果。当每个value值被测试,如果value


值为if1Decode函数的结果是then1;如果value等于if2Decode函数结果是then2;等等。事实上,可以给出


多个if/then配对。如果value结果不等于给出的任何配对时,Decode结果就返回else


q需要注意的是,这里的ifthenelse都可以是函数或计算表达式。



例子:



Create table sales(month char(2),sales_tvnumber,sales_computernumber);

Insert into sales values('01', 10, 18);

Insert into sales values('02', 28, 20);

Insert into sales values('03', 36, 33);





要求查询出最后两列中较大值:



SQL> selectsign(-111) from dual;//小于就返回-1大于返回1 等于返回0

SIGN(-111)

----------

-1




SQL> select sign(199) from dual;

SIGN(199)

----------

1

SQL> select month, decode(sign(s.sales_tv -       s.sales_computer),1,s.sales_tv,-1,s.sales_computer,0,s.sales_tv,s.sales_tv)

   from sales s;

MONTH DECODE(SIGN(S.SALES_TV-S.SALES

----- ------------------------------

01 18

02 28

03 36

SQL>






oracle的行列转换



create table销售(商品名称varchar2(10),季度char(2),销售额number);

insert into销售values('电视机', '01', 100);

insert into销售values('电视机', '02', 200);

insert into销售values('电视机', '03', 300);

insert into销售values('空调', '01', 50);

insert into销售values('空调', '02', 150);

insert into销售values('空调', '03', 180);


要求显示效果是:






格式1

商品名称 季度 销售额

---------- ---- ----------

电视机01 100

电视机02 200

电视机03 300

空调01 50

空调02 150

空调03 180



格式2

商品名称 一季度 二季度 三季度 四季度

---------- ---------- ---------- ---------- ----------

电视机100 200 300 0

空调50 150 180 0


首先是确定需要分组来进行的。还要明确的是聚合函数是在确定行或者分组以后对每行进行逐行执行的




再对分组的每个小组进行判断是使用了哪种季度

SQL> select xs.商品名称,

2sum(decode(xs.季度,'01',xs.销售额,0)) 第一季度,

       //对每行进行相加,只有通过decode来控制所被加的值是多少,

         不满足+0如果满足就+销售额


3 sum(decode(xs.季度,'02',xs.销售额,0)) 第二季度,

4 sum(decode(xs.季度,'03',xs.销售额,0)) 第三季度

5 from 销售 xs group by xs.商品名称 order by 1;

商品名称 第一季度 第二季度 第三季度

---------- ---------- ---------- ----------

电视机 100 200 300

空调 50 150 180




SQL>






ROWNUM的使用和TOP取前多少行






创建yggz

create tableyggz(

bhnumber(6) ,

gznumber

);



insert intoyggzvalues(1,1000);

insert intoyggzvalues(2,1100);

insert intoyggzvalues(3,900);

insert intoyggzvalues(4,2000);

insert intoyggzvalues(5,1500);

insert intoyggzvalues(6,3000);

insert intoyggzvalues(7,1400);

insert intoyggzvalues(8,1200);



作用:对查询结果,输出前若干条记录

注意:只能与<<=between
and
连用




查询 3号到5号的记录出来

方式1:通过集合相减

SQL> select bh,gz from yggz where rownum <=5

2 minus

3 select bh,gz from yggz where rownum <3;

BH GZ

------- ----------

   3 900

4 2000

5 1500




SQL>




方式2:通过取别名来处理

SQL> select * from (select yggz.*,rownum as rn from yggz) where rn <=5 and rn >= 3 ;

BH GZ RN

------- ---------- ----------

3 900 3

4 2000 4

5 1500 5




SQL>






注意:select * from (select * from student);

在oracle中这句话是可以的,但是在sql server中是不可以的必须个后面的语句起个别名才行




如何删除重复记录



create table student(snonumber(6) ,snamevarchar2(10),
sage
int);

insert into student values(1, 'AA',21);

insert into student values(2, 'BB', 22);

insert into student values(3, 'CC', 23);

insert into student values(3, 'CC', 34);

insert into student values(3, 'CC', 35);

insert into student values(3, 'CC', 36);




方式1:通过rowid(rowid所表示的是唯一标识一行记录,使用rowid 的方式查询记录是最快的)

     他表示段、区、块、行号所以唯一定位一行记录。

     和rownum一样都是伪列,默认是不显示的。



SQL> delete from student s where s.sno in(select sno from student group by sno having count(sno) > 1)

2 and

3 s.rowid not in (select min(rowid) from student group by sno having count(sno) > 1);

3 rows deleted

SQL>



方式2:自连接方式,首先观察下面的结果集


SQL> select * from student s1,student s2 where s2.sno = s1.sno;

SNO SNAME SAGE SNO SNAME SAGE

------- ---------- --------------------------------------- ------- ---------- ---------------------------------------

1 AA 21 1 AA 21

2 BB 22 2 BB 22

3 CC 36 3 CC 23

3 CC 35 3 CC 23

3 CC 34 3 CC 23

3 CC 23 3 CC 23


3 CC 36 3 CC 34

3 CC 35 3 CC 34

3 CC 34 3 CC 34

3 CC 23 3 CC 34

3 CC 36 3 CC 35

3 CC 35 3 CC 35

3 CC 34 3 CC 35

3 CC 23 3 CC 35

3 CC 36 3 CC 36

3 CC 35 3 CC 36

3 CC 34 3 CC 36

3 CC 23 3 CC 36

18 rows selected


通过结果集可以知道只要删除表1中的rowid大于表2的rowid就可以了,这样最先插入的记录的rowid最小就不会存在被删除的可能了

因为他找不到比他小rowid的记录


SQL> delete from student s where s.rowid in(

2 select s1.rowid from student s1 inner join student s2 on s1.sno = s2.sno where s1.rowid > s2.rowid);

3 rows deleted




SQL>



方式:3子查询的方式

SQL> delete from student s1 where s1.rowid > (

2 select min(s2.rowid) from student s2 where s1.sno = s2.sno);

3 rows deleted




SQL>






GROUP BY GROUPING SETS的使用


可以用GROUP BY GROUPING SETS来进行分组自定义汇总,可以应用它来指定你需要的总数组合。

其格式为:





GROUP BY GROUPING SETS ((list), (list) ... )

这里(list)是圆括号中的一个列序列,这个组合生成一个总数。要增加一个总和,必须增加一个(NUlL)分组集。




SQL>

SQL> SELECT CASE

2WHEN a.deptno IS NULL THEN

3 '合计'

4 WHENa.deptno IS NOT NULL ANDa.empno IS NULL THEN

5 '小计'

6 ELSE

7 '' || a.deptno

8 END deptno,

9 a.empno, a.ename,

10 SUM(a.sal) total_sal

11 FROM scott.emp a WHERE a.sal > 2000 GROUP BY GROUPING SETS((a.deptno),(a.deptno, a.empno, a.ename),());

注意:

1. 在select中出现的值必须在group by grouping sets中出现但是在聚合函数中出现的则不需要这样的要求

2. 在第一个list中出现的分组属性必须在第二个list中的分组属性出现产生一个递阶的效果

3. 在when中的判断第一个when判断第一个分组是否为空,一次类推。







DEPTNO EMPNO ENAME TOTAL_SAL

---------------------------------------- ----- ---------- ----------

10 7782 CLARK 2450

10 7839 KING 5000

小计 7450

20 7566 JONES 2975

20 7788 SCOTT 3000

20 7902 FORD 3000

小计 8975

30 7698 BLAKE 2850

小计 2850

合计 19275

10 rows selected




SQL>

DEPTNO EMPNO ENAME TOTAL_SAL

---------------------------------------- ----- ---------- ----------

10 7782 CLARK 2450

10 7839 KING 5000

小计 7450

20 7566 JONES 2975

20 7788 SCOTT 3000

20 7902 FORD 3000

小计 8975

30 7698 BLAKE 2850

小计 2850

合计 19275

10 rows selected




SQL>

SQL>

SQL>

SQL> SELECT CASE

2 WHEN a.deptno IS NULL THEN

3 '合计'

4 WHEN a.deptno IS NOT NULL AND a.empno IS NULL THEN

5 '小计'

6 ELSE

7 '' || a.deptno

8 END deptno,

9 a.empno, a.ename,

10 SUM(a.sal) total_sal

11 FROM scott.emp a WHERE a.sal > 2000 GROUP BY GROUPING SETS((a.deptno, a.empno, a.ename),());

DEPTNO EMPNO ENAME TOTAL_SAL

---------------------------------------- ----- ---------- ----------

10 7782 CLARK 2450

10 7839 KING 5000

20 7566 JONES 2975

20 7788 SCOTT 3000

20 7902 FORD 3000

30 7698 BLAKE 2850

合计 19275

7 rows selected




SQL>

SQL> SELECT CASE

2 WHEN a.deptno IS NULL THEN

3 '合计'

4 WHEN a.deptno IS NOT NULL AND a.empno IS NULL THEN

5 '小计'

6 ELSE

7 '' || a.deptno

8 END deptno,

9 a.empno, a.ename,

10 SUM(a.sal) total_sal

11 FROM scott.emp a WHERE a.sal > 2000 GROUP BY GROUPING SETS(());

SELECT CASE

WHEN a.deptno IS NULL THEN

'合计'

WHEN a.deptno IS NOT NULL AND a.empno IS NULL THEN

'小计'

ELSE

'' || a.deptno

END deptno,

a.empno, a.ename,

SUM(a.sal) total_sal

FROM scott.emp a WHERE a.sal > 2000 GROUP BY GROUPING SETS(())

ORA-00979: 不是 GROUP BY 表达式




SQL>

SQL> SELECT CASE

2 WHEN a.deptno IS NULL THEN

3 '合计'

4 WHEN a.deptno IS NOT NULL AND a.empno IS NULL THEN

5 '小计'

6 ELSE

7 '' || a.deptno

8 END deptno,

9 a.empno, a.ename,

10 SUM(a.sal) total_sal

11 FROM scott.emp a WHERE a.sal > 2000 GROUP BY GROUPING SETS((a.deptno),());

SELECT CASE

WHEN a.deptno IS NULL THEN

'合计'

WHEN a.deptno IS NOT NULL AND a.empno IS NULL THEN

'小计'

ELSE

'' || a.deptno

END deptno,

a.empno, a.ename,

SUM(a.sal) total_sal

FROM scott.emp a WHERE a.sal > 2000 GROUP BY GROUPING SETS((a.deptno),())

ORA-00979: 不是 GROUP BY 表达式




SQL>

SQL> SELECT CASE

2 WHEN a.deptno IS NULL THEN

3 '合计'

4 WHEN a.deptno IS NOT NULL AND a.empno IS NULL THEN

5 '小计'

6 ELSE

7 '' || a.deptno

8 END deptno,

9 a.empno, a.ename,

10 SUM(a.sal) total_sal

11 FROM scott.emp a WHERE a.sal > 2000 GROUP BY GROUPING SETS((a.deptno),(a.deptno, a.empno, a.ename));

DEPTNO EMPNO ENAME TOTAL_SAL

---------------------------------------- ----- ---------- ----------

10 7782 CLARK 2450

10 7839 KING 5000

小计 7450

20 7566 JONES 2975

20 7788 SCOTT 3000

20 7902 FORD 3000

小计 8975

30 7698 BLAKE 2850

小计 2850

9 rows selected




SQL>




SQL> SELECT CASE

2 WHEN a.deptno IS NULL THEN

3 '合计'

4 WHEN a.deptno IS NOT NULL AND a.empno IS NULL THEN

5 '小计'

6 ELSE

7 '' || a.deptno

8 END deptno,

9 a.empno, a.ename, a.sal,

10 SUM(a.sal) total_sal

11 FROM scott.emp a WHERE a.sal > 2000 GROUP BY GROUPING SETS((a.deptno),(a.deptno, a.empno, a.ename,a.sal),());

DEPTNO EMPNO ENAME SAL TOTAL_SAL

---------------------------------------- ----- ---------- --------- ----------

10 7782 CLARK 2450.00 2450

10 7839 KING 5000.00 5000

小计 7450

20 7566 JONES 2975.00 2975

20 7788 SCOTT 3000.00 3000

20 7902 FORD 3000.00 3000

小计 8975

30 7698 BLAKE 2850.00 2850

小计 2850

合计 19275

10 rows selected




SQL>










运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-298585-1-1.html 上篇帖子: SQL学习之存储过程 下篇帖子: SQL 常用函数总结
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表