SQL笔试之远交近攻

之所以叫远交近攻是因为本片为上一篇的进阶之作,夯实目前的SQL基础,为未来SQL的深入学习做一个承接的作用。

 

一 连接操作符(实现oracle中的for循环)用于快速删除表操作

SQL> select 'drop table '||tname||' purge;'  sqltxt from tab where tname not in ('EMP','DEPT','SALGRADE','BONUS');

SQLTXT

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

drop table T4 purge;

 

二 Rownum 和Rowid的伪列用法

 

2.1 查询工资倒数第5名到倒数第二名的员工信息:

select *from

(selectrownum row_num,ename,sal,hiredate,deptnofrom (select *from emporderby sal)whererownum <=6

where row_numbetween2and5 ;

 

   ROW_NUM ENAME             SAL     HIREDATE           DEPTNO

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

         2 JAMES             950       03-12-81            30

         3 ADAMS            1100     23-5 -87            20

         4 WARD             1250     22-2 -81            30

         5 MARTIN           1250     28-9 -81            30

 

注意如果使用如下语句会报错:

SQL> select rownum  row_num,ename,sal,hiredate,deptno  from (select * from emp order by sal) where row_num between 2 and 5;

ORA-00904: "ROW_NUM": 标识符无效

 

SQL> select  rownum,ename,sal,hiredate,deptno from ( select * from (select rownum row_num,ename,sal,hiredate,deptno from (select * from emp order by sal) where rownum <=6) where row_num between 2 and 5);

 

    ROWNUM ENAME             SAL   HIREDATE           DEPTNO

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

         1           JAMES             950    03-12-81            30

         2           ADAMS            1100   23-5 -87            20

         3           WARD             1250   22-2 -81            30

         4          MARTIN           1250   28-9 -81            30

 

    *注意这里的rownum与上例的ROW_NUM伪列的区别。

 

2.2 删除表中相同的条目

 

SQL> create table t7 as select * from emp;

表已创建。

SQL> insert into t7 select * from emp where empno=7788;

已创建 1 行。

SQL> commit;

提交完成。

 

SQL> select * from t7 where empno=7788;

 

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO

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

      7788 SCOTT      ANALYST         7566 19-4 -87          3000                    20

      7788 SCOTT      ANALYST         7566 19-4 -87          3000                    20

 

    任何的sql操作都有对象性可言,但相同的条目无法区分,这个时候需要借助于ROWID这个特殊列对该表进行操作。

 

SQL> delete t7 where rowid in (select max(rowid) from t7 where empno in (select empno from t7 group by empno having count(empno) > 1) group by empno);

 

已删除 1 行。

 

三 SQL与shell的结合

 

    虽然极少情况能碰到这种情况,但也被撞到了。暂且简单的介绍下!

--查找J开头S结尾的ename列,-i忽略大小写

SQL>  select ename from emp where regexp_like(ename,'^J.*s$','i');

 

ENAME

----------

JONES

JAMES

 

--替换修改

SQL>  select ename,regexp_replace(ename,'ES','Hn') re_name from emp where regexp_like (ename,'J..S');

ENAME      RE_NAME

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

JONES      JONHn

JAMES      JAMHn

 

Row_num分析函数的使用

 

  虽然只不过是个分析函数,但这个函数太重要了,应用的场景很多,笔试中也碰到了几次。

SQL> select  deptno,ename,sal,rn from (select deptno,ename,sal,row_number() over(partition by  deptno  order by sal desc) rn from emp)  where rn between  2 and 3;

    DEPTNO ENAME          SAL         RN

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

        10 CLARK            2450        2

        10 MILLER           1300        3

        20 FORD             3000        2

        20 JONES            2975        3

        30 ALLEN            1600        2

        30 TURNER           1500        3

 

已选择6行。

 

五  树形查询

 

   几乎涉及到组织网络模型的都要用到这个函数了,应用面也是非常的广泛

--查找KING下面组织的人,向下查询

    SQL>  select LEVEL,ename from emp start with (ename='KING') connect by prior empno= mgr  ;

 

     LEVEL ENAME

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

         1 KING

         2 JONES

         3 SCOTT

         4 ADAMS

         3 FORD

         4 SMITH

         2 BLAKE

         3 ALLEN

         3 WARD

         3 MARTIN

         3 TURNER

         3 JAMES

         2 CLARK

         3 MILLER

 

已选择14行。

--查找ADAMS组织的领导,向上查询

SQL>  select LEVEL,ename from emp start with (ename='ADAMS') connect by prior mgr=empno  ;

 

     LEVEL ENAME

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

         1 ADAMS

         2 SCOTT

         3 JONES

         4 KING

观察两者的区别,为了方便记忆,先看向下查询,由empno -- > mgr即是查找mgrKINGDempno的,然后逐级向下分析查询。然后看向上查询,同理,即是查找empno  ADAMSMGR的,然后逐级向上迭代查询。

 

SQL> break on deptno skip 1
SQL>  select deptno,LEVEL,grade,ename,sal,job from (select e.*,s.grade from emp e,salgrade s where e.sal between s.losal and s.hisal)

 start with (ename='KING') connect by prior empno= mgr order by 1,2;

    DEPTNO      LEVEL      GRADE   ENAME  SAL      JOB
     ----------   ----------      ---------- ----------  ---------- ---------
        10        1          5     KING             5000 PRESIDENT
                    2          4      CLARK           2450 MANAGER
                    3          2      MILLER          1300 CLERK

        20       2          4     JONES            2975 MANAGER
                    3          4      SCOTT            3000 ANALYST
                    3          4      FORD             3000 ANALYST
                    4          1      ADAMS           1100 CLERK
                    4          1      SMITH            800   CLERK

        30        2          4     BLAKE            2850 MANAGER
                    3          2      MARTIN         1250 SALESMAN
                    3          3      TURNER         1500 SALESMAN
                    3          1      JAMES            950   CLERK
                    3          3      ALLEN            1600 SALESMAN
                    3          2      WARD            1250 SALESMAN


已选择14行。

   这里很有意思MANAGER JONES 竟然没有员工挣得多,谁让SCOTT 和FORD是元老呢,呵呵!

  以上就是一些SQL常见的笔试题,SQL这个东西逻辑搞明白了,一些函数搜索下拿过来就用了。当然一天不要面太多家了,记得当初一天面了4家公司,到第5家的时候,已经是下午5点了,一天下来SQL题做到吐。也赶上了这个题比较恶心,从刚开始的表设计到最后的PL/SQL都较偏僻,结果做了10多分钟,也赶上人家5点半要下班,草草交了,这也算一次不成功的笔试了。所以面试也不能贪多求全了,注意身体,劳逸结合!

 

你可能感兴趣的:(oracle,sql)