[Postgre]id별 경우의 수 구하기 0 8 1,407

by 김선우 [DB 기타] Postgre 그룹별 경우의 수 [2017.07.24 15:54:40]


안녕하세요

그룹별 경우의 수를 구하고자 하는데 애를 먹고 있어요.

경우의 수를 오라클의 경우에는 간단히 구한다는 검색결과를 보고 참고하고자 했지만

Postgre의 경우에는 간단히 가능한 방법은 없나요?  아니면 조인방법으로라도...

ID     VAL

1       A

1       B

1       C

1       D

1       E

2       A

2       B

2       C

3       A

3       B

4       E

4       F

4       G

4       H

상기의 ID별 순서와 무관한 4개의 경우의 수를 구하고자 합니다. 4개의 경우의 수가 않되면 대상이 되지 않구요

경우의 수 내에서는 정렬되어 있어야하구요.

[결과표]

ID   PTN

1   A-B-C-D

1   A-C-D-E

1   B-C-D-E

4   E-F-G-H

더운 날씨에 건강 유의하시길....

 

by 마농 [2017.07.24 16:21:15]

원하시는 결과표를 보여주세요.


by 김선우 [2017.07.24 16:36:39]

본문의 조건과 결과표를 수정했습니다.

감사합니다.


by jkson [2017.07.24 17:14:36]

재귀쿼리를 써야할 것 같은 느낌적인 느낌


by jkson [2017.07.24 17:52:30]
with t (id, val) as
(
select '1', 'A' from dual union all
select '1', 'B' from dual union all
select '1', 'C' from dual union all
select '1', 'D' from dual union all
select '1', 'E' from dual union all
select '2', 'A' from dual union all
select '2', 'B' from dual union all
select '2', 'C' from dual 
)
, t2(id, val, path, lv, cnt) as
(
select id, val, cast(val as varchar2(4000)) 
     , 1     
     , count(1) over(partition by id) cnt
  from t
union all
select t.id, t.val, t2.path||'-'||t.val
     , lv + 1
     , cnt
  from t, t2
where instr(t2.path,t.val) = 0
  and t.id = t2.id
)
select path 
  from
    (
    select path, row_number() over(partition by id order by path) rn 
          ,count(1) over(partition by id) totcnt
    from t2
    where cnt = lv
    )
 where rn <= 4
   and totcnt >= 4

심심해서 oracle로 작성해봤는데..

비효율적이네요. 검색해보니

postgre도 with recursive 문으로 재귀 쿼리 가능한 거 같네요.

 


by 마농 [2017.07.24 18:32:37]

by jkson [2017.07.24 18:46:30]

아~ 순서와 무관하다는 게 val 값별 조합 순서가 무관하다는 말이었네요.

조합이 4건 이상인 것 중 아무거나 4건만 출력하면 된다는 말인 줄..

(다시 글을 읽어보니 이렇게 이해하기도 어렵겠네요.. 무한 자책중..ㅠㅠ)

아.. 쿼리보다 언어 이해력이 문제네요ㅋㅋ


by 마농 [2017.07.24 18:20:02]
WITH RECURSIVE t AS
(
SELECT id
     , val
     , 1 lv
     , val p
  FROM test
 UNION ALL
SELECT c.id
     , c.val
     , p.lv + 1 lv
     , p.p ||'-'|| c.val p
  FROM t p
 INNER JOIN test c
    ON p.id = c.id
   AND p.val < c.val
   AND p.lv + 1 <= 4
)
SELECT id
     , p
  FROM t
 WHERE lv = 4
;

 


by 김선우 [2017.07.24 19:14:03]

> by jkson님 감사합니다 충분히 참고가 되었습니다.

 

>마농님 완벽하네요. 제 머리로는 아직도 이해가 안되지만 ....감사합니다. 이제부터 이해하는데 시간을 투자하겠습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입