被sqlplus的break命令搞糊涂了

时间:2015-02-05 07:40:36

标签: oracle sqlplus

来自documentation of sqlplus for break

当指定多个on子句时,sqlplus将从第一个on子句搜索到最后一个on子句以进行中断。当它找到一个中断时,它将以相反的顺序执行操作,从最后一个到第一个。

我连接到scott架构并进行了一些测试:

SQL> break on deptno skip 1 on job skip 2
SQL> break
break on deptno skip 1 nodup
      on job skip 2 nodup

SQL> select deptno, job from emp order by deptno, job;    

    DEPTNO JOB
---------- ---------

        10 CLERK


           MANAGER


           PRESIDENT



        20 ANALYST

    DEPTNO JOB
---------- ---------
        20 ANALYST


           CLERK



           MANAGER




    DEPTNO JOB
---------- ---------
        30 CLERK


           MANAGER


           SALESMAN






 14 rows selected.

 SQL>

打印完第一行(10,CLERK)后,作业发生变化,它只跳过2行,为什么不跳3行?在第二页,有两个地方sqlplus跳过3行。在报告的最后跳过5行。只是不知道它如何决定在指定多个on子句时要跳过多少行。

2 个答案:

答案 0 :(得分:0)

你没有看到你的想法。您只需查询可能有重复项的部门和职位列,因为每个职位中可以有多名员工。中断设置的nodup部分意味着不会显示这两列的重复项;这意味着你看到混合的行,两列都被删除为重复列,以及被跳过的行。

我有一个不同的表,但效果相同:

break on department_id skip 1 on job_id skip 2

select department_id, job_id
from employees
where rownum < 10;

DEPARTMENT_ID JOB_ID
------------- ----------
           90 AD_PRES


              AD_VP




           60 IT_PROG







          100 FI_MGR




9 rows selected.

如果我添加另一个非空列和/或rownum伪列,您可以看到实际发生的事情:

    ROWNUM DEPARTMENT_ID JOB_ID     EMPLOYEE_ID
---------- ------------- ---------- -----------
         1            90 AD_PRES            100


         2               AD_VP              101
         3                                  102



         4            60 IT_PROG            103
         5                                  104
         6                                  105
         7                                  106
         8                                  107



         9           100 FI_MGR             108




9 rows selected.

现在,如果部门内的工作发生变化,您可以看到它跳过两行,当部门更改时,可以看到三行。这就是你要求它做的。

您可能不想,但您也可以获得不同的值:

select distinct department_id, job_id ...

DEPARTMENT_ID JOB_ID

       90 AD_VP


          AD_PRES



       60 IT_PROG



      100 FI_MGR

选择了4行。

...再次,您会在部门内的工作和部门之间看到两条跳过的线。

您可能也会混淆文档中的行为描述;你说&#34;当它发现休息时#34;但它可以在结果中找到一行的多个中断;您链接到的文档实际上说:

  

SQL * Plus在输出的每一行中搜索指定的中断,从最外面的中断开始,然后按照输入子句的顺序继续 - 到最里面。

使用您的查询,它将匹配部门,工作或两者。

  

接下来,SQL * Plus执行从为最里面的中断指定的操作开始的操作,并以相反的顺序向最外面的中断继续... SQL * Plus执行每个操作,包括为第一个中断遇到的操作。最初的搜索。

你的案件中最重要的休息是工作,最重要的部门。如果部门没有改变但是工作没有改变,那么它只能在工作中找到匹配的中断,并且只应用最里面的跳过(两行)。如果部门改变了 - 无论工作是否也发生了变化 - 它会找到匹配,但仍然会以相反的顺序应用部门以后的所有on条款;所以它将应用来自作业skip 1来自部门的skip 2;因此总共跳过三行。


是的我在没有订单的情况下使用rownum,它恰好可以更好地处理这个查询和我的数据;不要在家里试试

答案 1 :(得分:0)

  

打印完第一行(10,CLERK)后,作业有变化,它只跳过2行,为什么不是3行?

当您在作业跳过2 中提及时,为什么会跳过3行? SQL * Plus完全按照您的要求执行操作,跳过2行。

  

在第二页中,有两个地方sqlplus跳过3行。

那是因为你还提到在deptno上跳过1 因此,对于一个新部门,还有一行被跳过。因此,跳过2行作为工作,1行跳过部门,因此总共跳过3行。

此外,对于部门20,有 2 ANALYST 2 CLERK ,因此每个作业会跳过2行。

SQL> break on job skip 2
SQL> select deptno, job from emp order by deptno, job;

    DEPTNO JOB
---------- ---------
        10 CLERK


        10 MANAGER


        10 PRESIDENT


        20 ANALYST
        20


        20 CLERK
        20


        20 MANAGER


        30 CLERK


        30 MANAGER


        30 SALESMAN
        30
        30
        30



14 rows selected.

SQL>
  

在报告的最后跳过5行。

因为,在部门30的最后,有4个SALESMAN,并且在显示总行数消息之前总会有一个额外的行。

SQL> set pagesize 50
SQL> select deptno, job from emp order by deptno, job;

    DEPTNO JOB
---------- ---------
        10 CLERK
        10 MANAGER
        10 PRESIDENT
        20 ANALYST
        20 ANALYST
        20 CLERK
        20 CLERK
        20 MANAGER
        30 CLERK
        30 MANAGER
        30 SALESMAN
        30 SALESMAN
        30 SALESMAN
        30 SALESMAN

14 rows selected.

SQL>

理解这一点的最好方法是,添加另一个没有任何跳过的列,例如添加empno并查看实际跳过的行。

SQL> break on deptno skip 1 on job skip 2
SQL> select empno, deptno, job from emp order by deptno, job;

     EMPNO     DEPTNO JOB
---------- ---------- ---------
      7934         10 CLERK


      7782            MANAGER


      7839            PRESIDENT



      7788         20 ANALYST
      7902


      7876            CLERK
      7369


      7566            MANAGER



      7900         30 CLERK


      7698            MANAGER


      7654            SALESMAN
      7521
      7499
      7844




14 rows selected.

SQL>