2010-03-28 4 views
6

이 쿼리는 네트워크에서 지배적 인 세트를 가져옵니다. 그래서 예를 들어 네트워크에게 주어진이 쿼리에서 'ORA-01489 : 문자열 연결 결과가 너무 깁니다.'를 어떻게 제거 할 수 있습니까?

A<----->B
B<----->C
B<----->D
C<----->E
D<----->C
D<----->E
F<----->E

는, E
B
B, F
A, E
를 반환하지만 내가 문자열 방법을 사용하고 있기 때문에 대량의 데이터가 작동하지 않습니다 내 결과에. 내가 문자열 방법을 제거하고 용량이 큰 복잡한 쿼리 처리 복잡한 문자열을하고 싶지 않아 내 경험에 아무 소용이

With t as (select 'A' as per1, 'B' as per2 from dual union all 
     select 'B','C' from dual union all 
     select 'B','D' from dual union all 
     select 'C','B' from dual union all 
     select 'C','E' from dual union all 
     select 'D','C' from dual union all 
     select 'D','E' from dual union all 
     select 'E','C' from dual union all 
     select 'E','D' from dual union all 
     select 'F','E' from dual) 
,t2 as (select distinct least(per1, per2) as per1, greatest(per1, per2) as per2 from t union 
     select distinct greatest(per1, per2) as per1, least(per1, per2) as per1 from t) 
,t3 as (select per1, per2, row_number() over (partition by per1 order by per2) as rn from t2) 
,people as (select per, row_number() over (order by per) rn 
      from (select distinct per1 as per from t union 
        select distinct per2 from t) 
      ) 
    ,comb as (select sys_connect_by_path(per,',')||',' as p 
       from people 
       connect by rn > prior rn 
      ) 
    ,find as (select p, per2, count(*) over (partition by p) as cnt 
      from (
        select distinct comb.p, t3.per2 
        from comb, t3 
        where instr(comb.p, ','||t3.per1||',') > 0 or instr(comb.p, ','||t3.per2||',') > 0 
       ) 
      ) 
,rnk as (select p, rank() over (order by length(p)) as rnk 
      from find 
      where cnt = (select count(*) from people) 
      order by rnk 
     ) select distinct trim(',' from p) as p from rnk where rnk.rnk = 1` 

답변

0

에 있지만, 뷰 또는 뭔가를 반환하는 시도하고있다,이 쿼리는 매우 복잡하다 . 나는이 문제가 기존 쿼리의 최적화 라기보다는 다시 생각해보고 다른 접근법을 통해 얻을 수 있다고 생각한다.

근본적인 테이블은 어떻게 생겼으며 정확히 달성하려는 대상은 무엇입니까? 데이터 모델을 변경할 수 있습니까?

+0

위의 데이터 A <---> B, B <---> C ....가 기본 데이터입니다. 그들은 사용자 및 친구 관계의 한 형태를 나타냅니다. 나는이 주어진 네트워크 최소한의 지배 세트에서 설정 한 최소한의 지배를 찾기 위해 노력하고는 소셜 네트워크에서 집합 더 많은 정보를 원하시면 여기 설정에 주도권의 네트워크에있는 모든 사람과 친구가 사람들의 세트입니다 : http : //en.wikipedia.org/wiki/Dominating_set –

6

오라클의 한계 중 하나는 SQL이 4000자를 초과하는 VARCHAR2를 처리 할 수 ​​없다는 것입니다. 이 크기를 초과하는 문자열을 반환하려고하면 ORA-01489가 발생합니다. 이상적으로는 결과 집합을 여러 개의 작은 행으로 나누어야합니다. 또는 CLOB로 리턴 할 수도 있습니다.

이 코드를 자세히 보았다면서 나는 CLOB

흠으로 위를 반환 할 수있는 방법을

... 편집 내가가는 유일한 장소를 생각한다 ORA-1489는 다음 줄입니다.

select sys_connect_by_path(per,',')||',' as p 
from people 

TO_CLOB()에 그 전화를 싸기 쉽습니다. 불행하게도 P를 CLOB로 바꾸는 것은 후속 처리 ('뚜렷한 p , 파티션을 p로 나누기) 중 일부를 깨기 때문에 아마 옵션이 아닙니다. 죄송합니다.

다른 해결 방법에 관해서는

....

사이트는 오라클 공간에 대한 라이센스를 가지고 있습니까? 나는 많은 사이트가 아니라는 것을 알고 있지만, 당신이 운 좋은 사람들 중 하나라면 (그리고 10gR2 이상을 사용하고 있다면) Oracle Spatial Network Data Model (PDF)을 확인해야합니다.

sys_connect_by_path() 호출의 출력을 제한 할 방법이 없으면 PL/SQL에 구현하면됩니다. PIPELINED FUNCTION을 사용하여 최종 출력을 리턴 할 수 있으므로 SELECT 문에서 계속 호출 할 수 있습니다.

+0

CLOB?, 어떻게 CLOB로 위를 반환 할 수 있습니다. 더 설명해주세요. –

+0

+1 "hurl ORA-1489" – EvilTeach

관련 문제