网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 交易代码 > SQL语法 > 正文

oracle高级sql的参考资料

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务

【网学网提醒】:网学会员鉴于大家对十分关注,论文会员在此为大家搜集整理了“oracle高级sql的参考资料”一文,供大家参考学习


    1.集合操作
    学习oracle中集合操作的有关语句,掌握union,unionall,minus,interest的使用,能够描述结合运算,并且能够将多个查询组合到一个查询中去,能够控制行返回的顺序。
    包含集合运算的查询称为复合查询。见表格1-1
    表1-1
    OperatorReturnscontent
    UNION由每个查询选择的所有不重复的行并集不包含重复值
    UNIONALL由每个查询选择的所有的行,包括所有重复的行完全并集包含重复值
    INTERSECT由每个查询选择的所有不重复的相交行交集
    MINUS在第一个查询中,不在后面查询中,并且结果行不重复差集
    所有的集合运算与等号的优先级相同,如果SQL语句包含多个集合运算并且没有圆括号明确地指定另一个顺序,Oracle服务器将以从左到右的顺序计算。你应该使用圆括号来明确地指定带另外的集合运算的INTERSECT(相交)运算查询中的赋值顺序。
    Unionall效率一般比union高。
    1.1.union和unionall
    UNION(联合)运算
    UNION运算返回所有由任一查询选择的行。用UNION运算从多表返回所有行,但除去任何重复的行。
    原则:
    &;#1048707;?被选择的列数和列的数据类型必须是与所有用在查询中的SELECT语句一致。列的名字不必相同。
    &;#1048707;?联合运算在所有被选择的列上进行。
    &;#1048707;?在做重复检查的时候不忽略空(NULL)值。
    &;#1048707;?IN运算有比UNION运算高的优先级。
    &;#1048707;?在默认情况下,输出以SELECT子句的第一列的升序排序。
    全联合(UNIONALL)运算
    用全联合运算从多个查询中返回所有行。
    原则
    &;#1048707;?和联合不同,重复的行不被过滤,并且默认情况下输出不排序。
    &;#1048707;?不能使用DISTINCT关键字。
    使用:
    Selectstatementunion|unionallSelectstatement;
    1.2.intersect交集操作
    相交运算
    用相交运算返回多个查询中所有的公共行。无重复行。
    原则
    &;#1048707;?在查询中被SELECT语句选择的列数和数据类型必须与在查询中所使用的所有的SELTCT语句中的一样,但列的名字不必一样。
    &;#1048707;?相交的表的倒序排序不改变结果。
    &;#1048707;?相交不忽略空值。
    使用:
    SelectstatementintersectallSelectstatement;
    1.3.minus差集操作
    相减运算
    用相减运算返回由第一个查询返回的行,那些行不出现在第二个查询中(第一个SELECT语句减第二个SELECT语句)。
    原则
    &;#1048707;?在查询中被SELECT语句选择的列数和数据类型必须与在查询中所使用的所有的SELTCT语句中的一样,但列的名字不必一样。
    &;#1048707;?对于MINUS运算,在WHERE子句中所有的列都必须在SELECT子句中。
    集合运算的原则
    ?在两个SELECT列表中的表达式必须在
    数目上和数据类型上相匹配
    ?可以用圆括号改变执行的顺序
    ?ORDERBY子句:–只能出现在语句的最后–从第一个SELECT语句接收列名、别名,或者位置记号
    注:?除了UNIONALL,重复行自动被清除
    ?在结果中的列名是第一个查询中出现的列名
    ?除了UNIONALL,默认情况下按升序顺序输出
    2.exists和notexists的使用
    2.1.exists的使用
    Exists用于只能用于子查询,可以替代in,若匹配到结果,则退出内部查询,并将条件标志为true,传回全部结果资料,in不管匹配到匹配不到都全部匹配完毕,使用exists可以将子查询结果定为常量,不影响查询效果,而且效率高。如查询所有销售部门员工的,对比如下:
    INisoftenbetteriftheresultsofthesubqueryareverysmall
    WhenyouwriteaqueryusingtheINclause,you'retellingtherule-basedoptimizerthatyouwanttheinnerquerytodrivetheouterquery.
    WhenyouwriteEXISTSinawhereclause,you'retellingtheoptimizerthatyouwanttheouterquerytoberunfirst,usingeachvaluetofetchavaluefromtheinnerquery.
    Inmanycases,EXISTSisbetterbecauseitrequiresyoutospecifyajoincondition,whichcaninvokeanINDEXscan.However,INisoftenbetteriftheresultsofthesubqueryareverysmall.Youusuallywanttorunthequerythatreturnsthesmallersetofresultsfirst.
    In和exists对比:
    若子查询结果集比较小,优先使用in,若外层查询比子查询小,优先使用exists。因为若用in,则oracle会优先查询子查询,然后匹配外层查询,若使用exists,则oracle会优先查询外层表,然后再与内层表匹配。最优化匹配原则,拿最小记录匹配大记录。
    使用in
    selectlast_name,title
    froms_emp
    wheredept_idin
    (selectid
    froms_dept
    wherename='Sales');
    使用exists
    selectlast_name,title
    froms_empe
    whereexists
    (select'x'--把查询结果定为constant,提高效率
    froms_deptswheres.id=e.dept_idands.name='Sales');
    2.2notexists的使用
    与exists含义相反,也在子查询中使用,用于替代notin。其他一样。如查询不在销售部的员工
    selectlast_name,title
    froms_empe
    wherenotexists
    (select'x'--把查询结果定为constant,提高效率
    froms_deptswheres.id=e.dept_idands.name='Sales');
    3.with子句
    9i新增语法
    1.使用with子句可以让子查询重用相同的with查询块,通过select调用,一般在with查询用到多次情况下。
    2.with子句的返回结果存到用户的临时表空间中,只做一次查询,提高效率。
    3.有多个查询的时候,第1个用with,后面的不用with,并且用逗号隔开。
    5.最后一个with子句与下面的查询之间不能有逗号,只通过右括
    号分割,查询必须用括号括起来
    6.如果定义了with子句,而在查询中不使用,那么会报ora-32035错误:未引用在with子句中定义的查询名。(至少一个with查询的name未被引用,解决方法是移除未被引用的with查询)
    7.前面的with子句定义的查询在后面的with子句中可以使用。
    With子句目的是为了重用查询。
    语法:
    Withalias_nameas(select1),--as和select中的括号都不能省略
    alias_name2as(select2),--后面的没有with,逗号分割
    …
    alias_namenas(selectn)–与下面的查询之间没有逗号
    Select….
    如查询销售部门员工的:
    --withclause
    withaas
    (selectidfroms_deptwherename='Sales'orderbyid)
    selectlast_name,title
    froms_empwheredept_idin(select*froma);--使用select查询别名
    使用with子句,可以在复杂的查询中预先定义好一个结果集,然后在查询中反复使用,不使用会报错。而且with子句获得的是一个临时表,如果在查询中使用,必须采用selectfromwith查询名,比如
    Withcntas(selectcount(*)fromtable)
    Selectcnt+1fromdual;
    是错误的。必须是
    Withcntas(selectcount(*)shumufromuser_tables)
    Selectshumu+1fromcnt;
    --直接引用with子查询中的列别名。
    一个with查询的实例:
    查询出部门的总薪水大于所有部门平均总薪水的部门。部门表s_dept,员工表s_emp。
    分析:做这个查询,首先必须计算出所有部门的总薪水,然后计算出总薪水的平均薪水,再筛选出部门的总薪水大于所有部门总薪水平均薪水的部门。那么第1步with查询查出所有部门的总薪水,第2步用with从第1步获得的结果表中查询出平均薪水,最后利用这两次的with查询比较总薪水大于平均薪水的结果,如下:
    with
    --step1:查询出部门名和部门的总薪水
    dept_costsas(
    selecta.name,sum(b.salary)dept_total
    from
    s_depta,s_empb
    wherea.id=b.dept_id
    groupbya.name
    ),
    --step2:利用上一个with查询的结果,计算部门的平均总薪水
    avg_costsas(
    selectsum(dept_total)/count(*)dept_avg
    fromdept_costs
    )
    --step3:从两个with查询中比较并且输出查询结果
    selectname,dept_total
    fromdept_costs
    where
    dept_total>
    (
    selectdept_avg
    from
    avg_costs
    )
    orderbyname;
    从上面的查询可以看出,前面的with查询的结果可以被后面的with查询重用,并且对with查询的结果列支持别名的使用,在最终查询中必须要引用所有with查询,否则会报错ora-32035错误。
    再如有这样一个需求:一个查询,如果查询的结果行不满足是10的倍数,则补空行,直到是查询出的行数是10的倍数。例如:se
    lect*fromtrademark这个查询。
    withcntas(select10-mod(count(*),10)shumufromtrademark)–查询比10的倍数差几个空行
    selectid,name
    fromtrademark
    unionall--空行加进去
    selectnull,null--补空行
    fromdualconnectbyrownum<=(selectshumufromcnt);--10个中connectby可以使用子查询
    10g之前的写法
    withcntas(select10-mod(count(*),10)shumufromtrademark)–查询比10的倍数差几个空行
    selectid,name
    fromtrademark
    unionall--空行加进去
    selectnull,null--补空行
    fromall_objectswhererownum<=(selectshumufromcnt);--使用all_objects行比较多
    4.mergeinto合并资料
    语法:(其中as可以省略)
    MERGEINTOtable_nameAStable_alias
    USING(table|view|sub_query)ASalias
    ON(joincondition)
    WHENMATCHEDTHEN
    UPDATESET
    col1=col_val1,
    col2=col2_val
    WHENNOTMATCHEDTHEN
    INSERT(column_list)—多个列以逗号分割//可以不指定列
    VALUES(column_values);
    作用:将源数据(来源于实际的表,视图,子查询)更新或插入到指定的表中(必须实际存在),依赖于on条件,好处是避免了多个insert和update操作。Merge是一个目标性明确的操作符,不允许在一个merge语句中对相同的行insert或update操作。这个语法仅需要一次全表扫描就完成了全部工作,执行效率要高于INSERT+UPDATE。例子如下:
    droptablet;
    CREATETABLETASSELECTROWNUMID,A.*fromDBA_OBJECTSA;
    droptablet1;
    CREATETABLET1AS
    SELECTROWNUMID,OWNER,TABLE_NAME,CAST('TABLE'ASVARCHAR2(100))OBJECT_TYPE
    fromDBA_TABLES;
    select*fromdba_objects;
    select*fromdba_tables;
    MERGEINTOT1USINGT
    ON(T.OWNER=T1.OWNERANDT.OBJECT_NAME=T1.TABLE_NAMEANDT.OBJECT_TYPE=T1.OBJECT_TYPE)
    WHENMATCHEDTHENUPDATESETT1.ID=T.ID
    WHENNOTMATCHEDTHENINSERTVALUES(T.ID,T.OWNER,T.OBJECT_NAME,T.OBJECT_TYPE);--insert后面不写表示插入全部列
    MERGEINTOT1USINGT
    ON(T.OWNER=T1.OWNERANDT.OBJECT_NAME=T1.TABLE_NAME)
    WHENMATCHEDTHENUPDATESETT1.ID=T.ID
    WHENNOTMATCHEDTHENINSERTVALUES(T.ID,T.OWNER,T.OBJECT_NAME,T.OBJECT_TYPE);--常见错误,连接条件不能获得稳定的行,可以使用下面的用子查询
    MERGEINTOT1
    USING(SELECTOWNER,OBJECT_NAME,MAX(ID)IDfromTGROUPBYOWNER,OBJECT_NAME)T
    ON(T.OWNER=T1.OWNERANDT.OBJECT_NAME=T1.TABLE_NAME)
    WHENMATCHEDTHENUPDATESETT1.ID=T.ID
    WHENNOTMATCHEDTHENINSERTVALUES(T.ID,T.OWNER,T.OBJECT_NAME);
    SELECTID,OWNER,OBJECT_NAME,OBJECT_TYPEfromT
    MINUS
    SELECT*fromT1;
    droptablesubs;
    createtablesubs(msidnumber(9),
    ms_typechar(1),
    areacodenumber(3)
    );
    
    droptableacct;
    createtableacct(msidnumber(9),
    bill_monthnumber(6),
    ar
    eacodenumber(3),
    feenumber(8,2)default0.00);
    
    insertintosubsvalues(905310001,0,531);
    insertintosubsvalues(905320001,1,532);
    insertintosubsvalues(905330001,2,533);
    commit;
    mergeintoaccta--操作的表
    usingsubsbon(a.msid=b.msid)--使用原始数据来源的表,并且制定条件,条件必须有括号
    whenmatchedthen
    updateseta.areacode=b.areacode--当匹配的时候,执行update操作,和直接update的语法不一样,不需要制定表名
    whennotmatchedthen--当不匹配的时候,执行insert操作,也不需要制定表名,若指定字段插入,则在insert后用括号标明,不指定是全部插入
    insert(msid,bill_month,areacode)values(b.msid,'200702',b.areacode);
    
    
    
    另外,MERGE语句的UPDATE不能修改用于连接的列,否则会报错
    select*fromacct;
    select*fromsubs;
    --10g新特性,单个操作
    mergeintoaccta
    usingsubsbon(a.msid=b.msid)
    whennotmatchedthen--只有单个notmatched的时候,只做插入,不做更新,只有单个matched的时候,只做更新操作
    insert(a.msid,a.bill_month,a.areacode)values(b.msid,'200702',b.areacode);
    
    updateacctsetareacode=800wheremsid=905320001;
    deletefromacctwhereareacode=533orareacode=531;
    insertintoacctvalues(905320001,'200702',800,0.00);
    --删除重复行
    deletefromsubsbwhereb.rowid<(
    selectmax(a.rowid)fromsubsawherea.msid=b.msidanda.ms_type=b.ms_typeanda.areacode=b.areacode);
    --10g新特性,merge操作之后,只有匹配的update操作才可以,用deletewhere子句删除目标表中满足条件的行。
    mergeintoaccta
    usingsubsbon(a.msid=b.msid)
    whenMATCHEDthen
    updateseta.areacode=b.areacode
    deletewhere(b.ms_type!=0)
    whenNOTMATCHEDthen
    insert(msid,bill_month,areacode)
    values(b.msid,'200702',b.areacode)
    whereb.ms_type=0;
    --10g新特性,满足条件的插入和更新
    mergeintoaccta
    usingsubsbon(a.msid=b.msid)
    whenMATCHEDthen
    updateseta.areacode=b.areacode
    whereb.ms_type=0
    whenNOTMATCHEDthen
    insert(msid,bill_month,areacode)
    values(b.msid,'200702',b.areacode)
    whereb.ms_type=0;
    select*fromsubswherems_type=0;
    
  • 上一篇资讯: oralce学习资料总结
  • 下一篇资讯: oracle课程记录
  • 设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
    版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师