来自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子句时要跳过多少行。
答案 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>