테이블의 CONNECT BY LEVEL이 추가 행을 반환하는 이유는 무엇입니까?
수준별 연결을 사용하면 테이블에서 수행할 때 너무 많은 행이 반환되는 것 같습니다.무슨 일이 일어나고 있는지에 대한 논리는 무엇입니까?
다음 표를 가정합니다.
create table a ( id number );
insert into a values (1);
insert into a values (2);
insert into a values (3);
이 쿼리는 12개 행(SQL Fiddle)을 반환합니다.
select id, level as lvl
from a
connect by level <= 2
order by id, level
열 LVL 값이 1인 표 A의 각 행, 열 LVL이 2인 표 A의 각 행, 즉:
ID | LVL---+-----1 | 11 | 21 | 21 | 22 | 12 | 22 | 22 | 23 | 13 | 23 | 23 | 2
이 쿼리는 동일한 결과를 반환하는 이 쿼리와 동일합니다.
select id, level as lvl
from dual
cross join a
connect by level <= 2
order by id, level
왜 이 쿼리들이 12개의 행을 반환하는지 또는 ID 열의 각 값에 대해 LVL이 2인 행이 3개이고 LVL이 1인 행만 있는 이유를 이해할 수 없습니다.
"연결"된 레벨 수를 3으로 늘리면 ID. 1의 각 값에 대해 13개 행이 반환됩니다. 여기서 LVL은 1, 3이고 LVL은 2이고 9는 3입니다.이는 반환된 행이 표 A에서 LVL - 1의 거듭제곱에 해당하는 행의 수임을 의미하는 것으로 보입니다.
저는 이 쿼리들이 6개의 행을 반환하는 다음과 같을 것이라고 생각했습니다.
select id, lvl
from ( select level as lvl
from dual
connect by level <= 2
)
cross join a
order by id, lvl
그 문서는 저에게 무슨 일이 일어나야 하는지 설명하는 데 있어 특별히 명확하지 않습니다.이러한 능력에 무슨 일이 일어나고 있으며 왜 처음 두 쿼리는 세 번째 쿼리와 같지 않습니까?
때connect by
는 되지않다니습 없이 됩니다.start with
과 과prior
연산자, 하위 행을 상위 행에 결합하는 데 제한이 없습니다.이러한 상황에서 Oracle은 모든 행을 상위 레벨의 모든 행에 연결하여 가능한 모든 계층 순열을 반환합니다.
SQL> select b
2 , level as lvl
3 , sys_connect_by_path(b, '->') as ph
4 from a
5 connect by level <= 2
6 ;
B LVL PH
---------- ----------
1 1 ->1
1 2 ->1->1
2 2 ->1->2
3 2 ->1->3
2 1 ->2
1 2 ->2->1
2 2 ->2->2
3 2 ->2->3
3 1 ->3
1 2 ->3->1
2 2 ->3->2
3 2 ->3->3
12 rows selected
첫 번째 쿼리에서는 수준별로 연결합니다.따라서 레벨이 <= 1이면 각 레코드를 한 번씩 얻게 됩니다.수준이 <= 2이면 각 수준이 1회(수준 1의 경우) + N회(여기서 N은 표의 레코드 수)가 됩니다.결과를 제한할 다른 조건이 없는 상태에서 레벨에 도달할 때까지 모든 레코드를 테이블에서 선택하기 때문에 교차 결합하는 것과 같습니다.레벨 <= 3의 경우 이 작업은 각 결과에 대해 다시 수행됩니다.
3개의 레코드에 대해:
- Lvl 1: 3개의 기록(모두 레벨 1)
- Lvl 2: 레벨 1이 있는 3개의 레코드 + 레벨 2가 있는 3*3 레코드 = 12
- Lvl 3: 3 + 3*3 + 3*3 = 39(각각 13개의 레코드).
- Lvl 4: 패턴이 보이기 시작하나요? :)
교차 결합이 아닙니다.교차 조인은 이 쿼리 결과에 레벨 2가 있는 레코드만 반환하는 반면, 이 연결 기준으로 레벨 1이 있는 레코드와 레벨 2가 있는 레코드를 가져오므로 3*3 레코드가 아닌 3+3*3이 됩니다.
최종 쿼리를 다른 쿼리와 비교할 때 사과와 오렌지를 비교하는 것입니다. 레벨이 1행 이중 테이블과 격리되어 있기 때문입니다.
이 쿼리를 고려해 보겠습니다.
select id, level as lvl
from a
connect by level <= 2
order by id, level
즉, 테이블 세트부터 시작합니다(* From a 선택).그런 다음 반환된 각 행에 대해 이 행을 이전 행에 연결합니다.연결 기준으로 조인을 정의하지 않았으므로, 이것은 사실상 데카르트 조인입니다. 따라서 (1,2,3) 1의 3개 행이 2,1->3,2->1,2->3,3->1,3->2에 조인하고 그들도 스스로 조인할 때 이 조인은 레벨=2입니다. 그래서 우리는 9개의 조인을 가지고 있습니다.따라서 12개의 행(원래 "레벨 1" 행 3개 + 데카르트 집합)이 생성됩니다.
따라서 출력되는 행 수 = 행 수 + (행 수 ^2)
마지막 쿼리에서 레벨을 이 수준으로 분리합니다.
select level as lvl
from dual
connect by level <= 2
당연히 두 줄을 반환합니다.그러면 원래의 3개 행으로 데카르트되어 6개 행이 출력됩니다.
아래 기술을 사용하여 이 문제를 해결할 수 있습니다.
select id, level as lvl
from a
left outer join (select level l from dual connect by level <= 2) lev on 1 = 1
order by id
언급URL : https://stackoverflow.com/questions/13540661/why-does-connect-by-level-on-a-table-return-extra-rows
'programing' 카테고리의 다른 글
Angular 2의 요소에 RouterLink 또는 다른 속성 지시어를 조건부로 추가합니다. (0) | 2023.07.26 |
---|---|
Swagger가 Spring Boot을 사용하여 Spring Data Rest API를 감지하지 못함 (0) | 2023.07.21 |
봄 부츠와 그라들이 있는 CTRL+C는 그라들 데몬을 죽인다. (0) | 2023.07.21 |
write(write) 대 writeline(write string (0) | 2023.07.21 |
Oracle에서 IPv4/IPv6 주소 표시 (0) | 2023.07.21 |