각 교집합 구하는 쿼리 문의 드립니다. 0 7 1,683

by 아이뻐 [2013.01.17 11:05:13]


안녕하세요
항상 고민하는 쿼리지만 심풀하게 나오질 않네요~

select 'A' Id, 111 site_id from dual union all
select 'B' Id, 111 site_id from dual union all
select 'C' Id, 111 site_id from dual union all
select 'D' Id, 111 site_id from dual union all
select 'E' Id, 111 site_id from dual union all
select 'B' Id, 222 site_id from dual union all
select 'C' Id, 222 site_id from dual union all
select 'D' Id, 222 site_id from dual union all
select 'T' Id, 222 site_id from dual union all
select 'A' Id, 333 site_id from dual union all
select 'B' Id, 333 site_id from dual union all
select 'C' Id, 333 site_id from dual union all
select 'U' Id, 333 site_id from dual union all
select 'A' Id, 444 site_id from dual union all
select 'B' Id, 444 site_id from dual union all
select 'C' Id, 444 site_id from dual union all
select 'D' Id, 444 site_id from dual union all
select 'E' Id, 444 site_id from dual union all
select 'F' Id, 444 site_id from dual union all
select 'G' Id, 444 site_id from dual
보시면 SITE_ID에 ID가 포함되있고 사이트당 ID는 유니크하게 존재 합니다.
제가 구하고 싶은건 (111과222) ,(111과333) ,(111과444), (222,333), (222,444), (333,444) 
중복 아이디를 구하는 것입니다.
결과가
EX) ID , SITE_ID
   B   111+222
   C   111+222
   D   111+222
   A   111+333
.     .
    .     .
    .     .
   C   333+444
이런 식으로 나와야 하는 쿼리입니다.
어찌 보면 각 사이트마다 서로의 교집합을 구하는 건데 그냥  INTERSECT를 사용하는 쿼리로는 가능하지만
SITE_ID가 많을 때는 그만큼 시간이 투자가 되더라고요. 고수님들의 능력을 빌어 좀 심플한 쿼리로 변경하고 싶습니다.
방법 좀 알려주시면 감사하겠습니다.
by 아발란체 [2013.01.17 11:21:06]

질문, B가 site_id 111, 222, 3333, 4444 있는데
결과 보면 B 111+222 로 되었는데
어떤 기준으로 B가 111+222 되었는지용? @.@)?
그냥 순서대로 2개씩 그룹하나요?
B 111+222
B 333+444 식으로용? ㅋㅅㅋ)?


by 아발란체 [2013.01.17 11:39:06]
SELECT
  ID, WM_CONCAT(site_id) AS site_id
FROM (
  SELECT
    id, site_id, CEIL(ROW_NUMBER() OVER(PARTITION BY id ORDER BY site_id) / 2) AS p
  FROM (
    select 'A' Id, 111 site_id from dual union all
    select 'B' Id, 111 site_id from dual union all
    select 'C' Id, 111 site_id from dual union all
    select 'D' Id, 111 site_id from dual union all
    select 'E' Id, 111 site_id from dual union all
    select 'B' Id, 222 site_id from dual union all
    select 'C' Id, 222 site_id from dual union all
    select 'D' Id, 222 site_id from dual union all
    select 'T' Id, 222 site_id from dual union all
    select 'A' Id, 333 site_id from dual union all
    select 'B' Id, 333 site_id from dual union all
    select 'C' Id, 333 site_id from dual union all
    select 'U' Id, 333 site_id from dual union all
    select 'A' Id, 444 site_id from dual union all
    select 'B' Id, 444 site_id from dual union all
    select 'C' Id, 444 site_id from dual union all
    select 'D' Id, 444 site_id from dual union all
    select 'E' Id, 444 site_id from dual union all
    select 'F' Id, 444 site_id from dual union all
    select 'G' Id, 444 site_id from dual 
  )
)
GROUP BY
  id, p
ORDER BY 
  id, site_id
;

by 마농 [2013.01.17 11:51:04]
SELECT id
     , SUBSTR(SYS_CONNECT_BY_PATH(site_id, '+'), 2) site_id
  FROM t
 WHERE LEVEL = 2
 CONNECT BY PRIOR id = id
 AND PRIOR site_id < site_id
 ORDER BY site_id, id
;

by 아이뻐 [2013.01.17 11:52:40]

설명을 제가 못했나보네요~ 집합으로 생각 하시면 111,222,333,444라는 집합이 있는데
각 집합의 교집합을 나타내는 것입니다.
(111∩222),(111∩333),(111∩444),(222∩333),(222∩444),(333∩444) 이것들이 결과로 보여 져야하는 것이죠

by 마농 [2013.01.17 12:04:13]
SELECT a.id
     , a.site_id ||'+'|| b.site_id site_id
  FROM t a
     , t b
 WHERE a.id = b.id
   AND a.site_id < b.site_id
 ORDER BY site_id, id
;

by 아발란체 [2013.01.17 12:11:16]
 마농님은 천재!!!

by 아이뻐 [2013.01.17 13:20:18]

아발란체님 답변 감사합니다. 그리고 그 열정 정말 닮고 싶습니다.
또한 천재란 말에 동감 합니다. 궁금한 쿼리 올릴때 항상 마농님 쿼리를 기대하는데 역시나....
완전 감사합니다.

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