zoukankan      html  css  js  c++  java
  • Oracle_SQL(7) 复杂查询

    1.rownum 伪列
    <,<=
    select * from emp where rownum<5;
    取工资前3名的人员
    select * from
    (select * from emp order by sal desc)
    where rownum<=3;
    取每个部门工资的最大值
    select deptno,max(sal) from emp group by deptno order by max(sal) desc

    取每个部门工资最大的人员
    select * from emp,
    (select deptno,max(sal) sal from emp group by deptno) emax
    where (emp.deptno=emax.deptno or emp.deptno is null and emax.deptno is null)
    and emp.sal=emax.sal

    取工资第二名的人员
    select * from emp where sal=
    (select max(sal) from emp where empno in
    (select empno from emp
    minus
    select empno from emp where sal=(select max(sal) from emp)))

    取每个部门工资第二的人员
    select * from emp,
    (select deptno,max(sal) sal from
    (select * from emp
    minus
    select emp.* from emp,
    (select deptno,max(sal) sal from emp group by deptno) emax
    where (emp.deptno=emax.deptno or emp.deptno is null and emax.deptno is null)
    and emp.sal=emax.sal)
    group by deptno) esed
    where emp.deptno=esed.deptno and emp.sal=esed.sal

    获取工资2到5名的职员
    select * from
    (select emp.*,rownum rn from
    (select * from emp order by sal desc) emp
    where rownum<=5)
    where rn>1

    2.分页查询
    &pages 当前页码
    &counts 每页行数
    select * from
    (select emp.*,rownum rn from
    (select * from emp order by empno) emp
    where rownum<=&pages*&counts)
    where rn>=(&pages-1)*&counts+1

    3.工作日统计
    declare
    v_start varchar2(10);
    v_end varchar2(10);
    v_tianshu number;
    v_zhou number;
    v_yushu number;
    v_zhoumo number:=0;
    v_result number;
    v_date date;
    v_diji number;
    begin
    v_start:='&p_start';
    v_end:='&p_end';
    select to_date(v_end,'yyyy-mm-dd')-to_date(v_start,'yyyy-mm-dd') into v_tianshu from dual;
    select trunc(v_tianshu/7),mod(v_tianshu,7) into v_zhou,v_yushu from dual;
    if v_yushu!=0 then
    v_date:=to_date(v_start,'yyyy-mm-dd')+v_zhou*7;
    for rs in 0..v_yushu-1 loop
    select to_char(v_date+rs,'d') into v_diji from dual;
    if v_diji=1 or v_diji=7 then
    v_zhoumo:=v_zhoumo+1;
    end if;
    end loop;
    end if;
    v_result:=v_zhou*5+v_yushu-v_zhoumo;
    dbms_output.put_line('工作日:'||v_result);
    end;

    4.删除重复记录
    有主键的表,除主键列外,其它列可能重复,主键列列。
    create table emp1 as select * from emp;
    alter table emp1 add constraints pk_emp1 primary key (empno);
    insert into emp1 (empno,ename,deptno) (select empno+1000,ename,deptno from emp where deptno=20);
    select * from emp1 order by deptno,empno;
    连主键都没有的表,所有列都可能重复,只有伪列rowid不重复。
    create table emp2 as select * from emp;
    insert into emp2 (empno,ename,deptno) (select empno,ename,deptno from emp where deptno=30);
    select emp2.*,rowid from emp2 order by deptno,empno;

    对于重复记录来说,我们需要先确定判断重复的依据,比如ename。
    select ename,count(*) from emp1 group by ename having count(*)>1;
    select ename,count(1) from emp2 group by ename having count(1)>1

    删除重复记录(1):有主键
    删前边的记录,保留后边的记录;
    delete from emp1 d where empno<any(select empno from emp_1 where ename=d.ename);
    delete from emp1 d where exists (select empno from emp1 where ename=d.ename and d.empno<empno);

    删后边的记录,保留前边的记录;
    delete from emp1 d where empno>any(select empno from emp_1 where ename=d.ename);

    删除重复记录(2):无主键
    删前边的记录,保留后边的记录;
    delete from emp2 d where rowid<any(select rowid from emp2 where ename=d.ename);
    删后边的记录,保留前边的记录;
    delete from emp2 d where rowid>any(select rowid from emp2 where ename=d.ename);

    5.条件查询case when
    select emp.*,case deptno
    when 10 then '10部门名'
    when 20 then '20部门名'
    when 30 then '30部门名'
    when 40 then '40部门名' end case
    from emp;
    =》
    select emp.*,decode(deptno,10,'10部门名',20,'20部门名',30,'30部门名',40,'40部门名' ) from emp;

    select emp.*,case
    when sal<1000 then '工资小于1000'
    when sal<2000 then '工资小于2000'
    when sal<3000 then '工资小于3000'
    else '工资大于等于3000' end case
    from emp;
    =》
    select emp.*,decode(sign(sal-1000),-1,'工资小于1000' ,
    decode(sign(sal-2000),-1,'工资小于2000' ,
    decode(sign(sal-3000),-1,'工资小于3000' ,'工资大于等于3000')))
    from emp;

    6.with as 语句
    作用:将重复使用的sql语句放置在with as 语句中,并设置别名,后续操作引用别名即可,以减少重复sql的执行次数。
    with a as (select * from emp where deptno=30)
    select * from a

    7.父子查询
    语法:
    select * from table [start with condition1]
    connect by [prior] id=parentid
    说明:
    [start with condition1]:用来限制第一层的数据,以第一层为基础来查找第二层,并以此类推
    connect by [prior] id=parentid :用来指明父子关系,及用第一层的id和第二层的parentid匹配
    connect by id=[prior] parentid :从下层往上层
    level列:树形结构中的层级编号
    connect_by_root(字段名)列:获取第一层集结点结果集中的任意字段的值
    举例:
    从上向下
    select emp.*,level,connect_by_root(ename) from emp start with mgr is null
    connect by prior empno=mgr
    从下向上
    select emp.*,level,connect_by_root(ename) from emp start with empno=7369
    connect by empno=prior mgr

    8.merge into插入或更新
    合并两个表的数据,主键不存在则新增,存在则更新。
    语法:
    merge into 表1
    using 表2
    on (条件)
    when not matched then
    insert values(表2.列) where 表2.列=?
    when matched then
    update set 表1.列=表2.列 where 表1.列=表2.列

    9.分析函数OVER (PARTITION BY
    9.1 SUM *
    SELECT mgr,sal,sum(sal) OVER (PARTITION BY mgr),
    sum(sal) OVER (PARTITION BY mgr ORDER BY sal),
    sum(sal) OVER (PARTITION BY mgr ORDER BY sal RANGE UNBOUNDED PRECEDING) l_csum
    FROM emp;
    --范围无限的前面
    9.2 AVG *
    select mgr,sal,avg(sal) OVER (PARTITION BY mgr),
    avg(sal) OVER (PARTITION BY mgr ORDER BY sal),
    avg(sal) OVER (PARTITION BY mgr ORDER BY sal ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
    from emp;
    --前后延1行
    9.3 MAX *
    SELECT ename,mgr,sal,
    MAX(sal) OVER (PARTITION BY mgr) AS mgr_max
    FROM emp;
    --按照mgr分组
    9.4 MIN *
    SELECT ename,mgr,hiredate,sal,
    MIN(sal) OVER(PARTITION BY mgr ORDER BY hiredate RANGE UNBOUNDED PRECEDING) as p_cmin
    FROM emp;
    --按照hiredate排序
    9.5 COUNT *
    SELECT ename,mgr,sal,
    COUNT(*) OVER (PARTITION BY mgr ORDER BY sal RANGE UNBOUNDED PRECEDING) AS mov_count FROM emp;
    --前面无限的范围

  • 相关阅读:
    自然语言处理(三)——PTB数据的batching方法
    自然语言处理(二)——PTB数据集的预处理
    自然语言处理(一)——语言模型评价方法
    TensorFlow数据集(二)——数据集的高层操作
    TensorFlow数据集(一)——数据集的基本使用方法
    TensorFlow多线程输入数据处理框架(四)——输入数据处理框架
    Node的简介
    seajs的原理以及基本使用
    git常用指令
    一个小白的四次前端面试经历
  • 原文地址:https://www.cnblogs.com/BradMiller/p/9279555.html
Copyright © 2011-2022 走看看