database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
ㆍOracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
Oracle Q&A 40809 게시물 읽기
No. 40809
퀴즈입니다. SQL로 집합의 모든 순서관계 순서쌍 구하기
작성자
김흥수(protokhs)
작성일
2015-05-28 14:38
조회수
9,109

다음과 같은 집합이 있습니다.

{1,2,3}

이 집합을 가능한 모든 순서의 순서쌍으로 나타내면 다음과 같습니다.

{ (1,2,3) , ( 2,1,3) , (2,3,1) , (1,3,2), ( 3,1,2) , ( 3,2,1 ) }

 

데이타로 '1,2,3' 이 주어질 때 위의 결과를 구하는 SQL을 작성하십시오.

with base_data as 
(
    select '1,2,3' v from dual
)
 
 
원하는 결과 ( 순서는 무관)
결과
3,2,1
2,3,1
2,1,3
3,1,2
1,3,2
1,2,3

 

이 글에 대한 댓글이 총 4건 있습니다.

with base_data as (

    select '1,2,3' v from dual

)

, temp as (

 select regexp_substr(t1.v, '[^,]+', 1, level) v

   from base_data t1

connect by level <= length(regexp_replace(t1.v, '[^,]+', ''))+1

)

select substr(sys_connect_by_path(v, '-'), 2) as path

  from temp x

 where level = 3

connect by nocycle prior x.v <> x.v


 

팡(pangs)님이 2015-05-28 15:34에 작성한 댓글입니다.
이 댓글은 2015-05-28 15:35에 마지막으로 수정되었습니다.

SELECT SUBSTR(SYS_CONNECT_BY_PATH(v, ','), 2) p
  FROM (SELECT REGEXP_SUBSTR(v, '[^,]+', 1, LEVEL) v
          FROM base_data
         CONNECT BY LEVEL <= REGEXP_COUNT(v, ',') + 1
        )
 WHERE CONNECT_BY_ISLEAF = 1
 CONNECT BY NOCYCLE PRIOR v != v
;

마농(manon94)님이 2015-05-28 18:02에 작성한 댓글입니다.

 훌륭하십니다.

 

nocycle을 그렇게 사용할 수 있네요...

다음은 제가 생각한 답입니다.

 

with base_data as 

(

    select '1,2,3' v from dual

)

, base_calc as

(

    select 

        ','||a.v v

        , length(','||a.v) - length(replace(','||a.v,',','') ) len

    from    base_data a

)

, base_recur ( v , len , tar, tarlen,pos ) as

(

    select

        a.v

        ,a.len

        ,substr( a.v , 1 ,nvl(nullif(instr( a.v , ',' , 1,2 ),0),length(a.v)+1) - 1  ) tar

        , 2 tarlen

        , 2 pos

    from    base_calc a

    union all

    select

        a.v

        ,a.len

        ,substr(a.tar,1, nvl(nullif(instr(a.tar,',',1,b.column_value),0),length(a.tar)+1) - 1)||substr(a.v,instr(a.v,',',1,a.pos) , nvl(nullif(instr(a.v,',',1,a.pos+1),0),length(a.v)+1) - instr(a.v,',',1,a.pos) )||substr(a.tar,nvl(nullif(instr(a.tar,',',1,b.column_value),0),length(a.tar) + 1))

        ,a.tarlen + 1

        ,a.pos + 1

    from    base_recur a

            , TABLE(select collect(level) from dual connect by level<= a.tarlen) b 

    where   a.pos <= a.len

)

select

    substr(a.tar,2) tar

from    base_recur a

where   a.len + 1 = a.pos

/

 

 

부분 순열에 각 각 위치로 새 원소를 삽입하는 방법으로 재귀호출하는 형태로 구현했습니다.

그런데 두 분의 방법이 훨씬 깔끔하네요...

 

그러면 또 다음 문제를 풀어보시기 바랍니다.

김흥수(protokhs)님이 2015-05-29 02:04에 작성한 댓글입니다.

아.. 조건으로는 connect_by_isleaf 으로 체크하는게 맞겠네요.

마농님 답변 항상 잘보고 있습니다. ^^

흥수님 퀴즈 감사합니다~

팡(pangs)님이 2015-05-29 11:06에 작성한 댓글입니다.
이 댓글은 2015-05-29 11:06에 마지막으로 수정되었습니다.
[Top]
No.
제목
작성자
작성일
조회
40812쿼리 질문드립니다. [2]
2015-06-02
7072
40811퀴즈입니다. SQL로 구문트리화된 수식을 계산하기 [5]
김흥수
2015-06-01
10711
40810퀴즈입니다. 부분수열의 순열들을 모두 구하기 (공집합은 제외) [3]
김흥수
2015-05-29
8937
40809퀴즈입니다. SQL로 집합의 모든 순서관계 순서쌍 구하기 [4]
김흥수
2015-05-28
9109
40808퀴즈입니다. 공집합을 제외한 모든 멱집합의 원소를 출력하는 SQL [4]
김흥수
2015-05-27
8916
40807모든 테이블에 하나라도 없는 값은 테이블명 출력? [1]
궁금이
2015-05-27
7427
40806사용자로그 관리에 대해 여쭤봅니다. [2]
예진예랑
2015-05-26
7197
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.021초, 이곳 서비스는
	PostgreSQL v16.4로 자료를 관리합니다