2012-07-05 3 views
1

형제 그룹을 식별하기 위해 일부 레코드를 함께 연결하려고합니다. 우리가 할 수있는 방법은 같은 부모님을 공유하는 고객을 찾는 것입니다.하나 또는 여러 기준으로 레코드 연결 및 계산

는 SQL의 샘플은 다음과 같습니다

다음과 같은 형식으로 데이터를 반환
SELECT 
A.ClientID, 
B.ParentID 

FROM A 
LEFT JOIN B ON B.ClientID to A.ClientID 
AND B.REL_END is NULL AND B.REL_CODE = 'PAR' 

:

 Client ID  Parent ID 
    1    A 
    1    B 
    2    C 
    2    D 
    3    C 
    3    E 
    4    C 
    4    D 

나는 그것을 표시 할 방법은 다음과 같습니다

 Client ID No. of Siblings 
    1   0 
    2   2 
    3   2 
    4   2   

바라건대 테이블에 따르면 자식 1에는 0 형제가 있고 (2,3,4를 가진 부모는 없습니다), 자식 2는 형제가 2 개 (3 및 4), 자식 3은 2 명의 형제 (2 및 4), 자식 4는 2 명의 형제 (2,3)가 있습니다. 이 일을 성취 할 수있을만큼 간단해야 할 것 같지만, 어떻게 생각 하느냐에 관해서는 정말 고심하고 있습니다! 나는 아이가 하나의 부모만을 다른 아이와 형제로 간주하기 때문에 약간 혼란 스럽다고 생각합니다.

잘하면 감사합니다.

편집 : 관계를 명확히하기 위해 부모 ID를 다른 자식과 공유하는 자식이 관계를 식별합니다 (ID는 고유하지만이 예에서는 일반적인 ID를 제공했습니다). 따라서 어린이 2, 3 및 4는 모두 C라는 ID를 가진 부모를 가졌으므로 형제로 간주됩니다.

답변

1

이것은 다소 복잡합니다. 이것이 수행하는 각 클라이언트에 대해 두 부모를 계산이다

select c.*, count(*) over (partition by min_parent, max_parent) - 1 as NumSiblings 
from (SELECT A.ClientID, min(B.ParentID) as min_parent, max(b.parentid) as max_parent 
     FROM A LEFT JOIN 
      B 
      ON B.ClientID to A.ClientID AND B.REL_END is NULL AND B.REL_CODE = 'PAR' 
     group by a.clientid 
    ) c 

: 각 자녀에 대해 정확히 두 부모 가정 할 경우에, 당신은 뭔가를 할 수 있습니다. 그런 다음 windows 함수를 사용하여 정확하게 동일한 부모를 가진 클라이언트 수를 계산합니다. "-1"은 모든 어린이가 집계되기 때문에 현재 어린이를 집계하고 싶지 않습니다.

부모가 두 명 이상일 수있는 경우 쿼리가 더 복잡합니다.

만 한 부모는 (오히려이보다) 공유되고 싶은 경우에, 당신은 자기를 사용하여 처리 할 수 ​​있습니다 가입 :

with cp as (SELECT A.ClientID, B.ParentID 
      FROM A LEFT JOIN 
       B 
       ON B.ClientID to A.ClientID AND B.REL_END is NULL AND B.REL_CODE = 'PAR' 
      ) 
select cp.client_id, count(distinct cp1.client_id) as NumSiblings 
from cp left outer join 
    cp cp1 
    on cp.parent_id = cp1.parent_id and cp.client_id <> cp1.client_id 
group by cp.client_id 
+0

@ Gordon Linoff : 답장을 보내 주셔서 감사합니다. 불행히도, 나는 또한 아이가 부모를 공유했지만 그 부모가 정확히 동일하지는 않았다 (아이 1은 부모 a와 b를 가질 수 있었고 아이 2는 부모 a와 c를 가질 수 있음) -이 경우 부모님을 공유하는 형제로 간주 될 수 있습니다.) - 저는 이것을 실행했으며 확실히 한 부모를 공유하는 사람이 아니라 같은 부모를 가진 사람을 선택합니다. 그래도 적어도 내가 생각했던 것처럼 간단하지는 않다는 것을 안심할 수는 있습니다. – bawpie

+0

감사합니다. 두 번째 쿼리가 제대로 작동하는 것 같습니다. 귀하의 도움을 많이 부탁드립니다! – bawpie

0

글쎄, 나는 테이블과 관계가 어떻게 만들어 지는지 이해하지 않는,하지만 당신은 그런 일 할 수있는 : 당신의 요구를 데려의 합을 반환하는 두 번째 결과를 수정 :

SELECT ClientID, sum(NumberOfSibling) as NumberOfSibling 
from(
    SELECT A.ClientID, (select count(ClientID) 
         from A2 
         LEFT JOIN B2 ON B2.ClientID to A2.ClientID 
         AND B2.REL_END is NULL AND B2.REL_CODE = 'PAR' 
         where B2.ParentID = B.ParentID) as NumberOfSibling 
    FROM A 
    LEFT JOIN B ON B.ClientID to A.ClientID 
    AND B.REL_END is NULL AND B.REL_CODE = 'PAR' 
) GROUP BY ClientID 

설명 형제는 동일한 부모 (즉, 조건에 대해 잘 모르는 부분 인 the select count(*) ...)를 소유하고 있습니다. 그리고이 값을 다른 것으로 두어 부모를 합친 값으로 ClientID를 그룹화합니다.

+0

답장을 보내 주셔서 감사합니다. 이해할 수는 없지만 B2가 작동하도록 선언해야합니까? 또한 LEFT JOIN B ON B2.ClientID는 A2.ClientID가 LEFT JOIN B ON이어야합니다. B2.ClientID = A2.ClientID 'to'를 사용할 때 잘못된 관계 연산자 오류가 발생합니다. – bawpie

+0

죄송합니다. 오류가 수정되었으며 설명을 추가했습니다. – wishper

+0

불행히도 도움을 주셔서 감사합니다.이 경우에는이 검색어가 작동하지 않습니다. 이는 내 자신의 부적응 때문인 것으로 의심됩니다. – bawpie

2

당신은이 쿼리를 시도 할 수 있습니다, 그것은 원하는 출력 내게 표시합니다.

with c_data as (
    select a.clientid, b.parentid, count(a.clientid) over (partition by parentid order by  parentid) as c_parents 
    FROM A 
     LEFT JOIN B ON (B.ClientID = A.ClientID) 
     AND B.REL_END is NULL AND B.REL_CODE = 'PAR' 
) 
select clientid as "Client ID", max(c_parents) -1 as "No of Siblings" 
from c_data 
group by clientid; 

예 : 우리가 카운트 분석 기능으로

SQL> with c_data as (
    2 select a.clientid, b.parentid, count(a.clientid) over (partition by parentid order by parentid) as c_parents 
    3 FROM A 
    4 LEFT JOIN B ON (B.ClientID = A.ClientID) 
    5 AND B.REL_END is NULL AND B.REL_CODE = 'PAR' 
    6 ) 
    7 select clientid as "Client ID", max(c_parents) -1 as "No of Siblings" 
    8 from c_data 
    9 group by clientid; 

Client ID No of Siblings 
---------- -------------- 
     1    0 
     2    2 
     4    2 
     3    2 

Transcurrido: 00:00:00.03 
SQL> 

모든 클라이언트 ID의 일반적인 같은 상위에있는 모든 클라이언트를 계산하는 현재 tupple의 관련 parentid에 의해 분할.

투영 후에 각 클라이언트에 대해 최대 수의 parent를 얻고 클라이언트 자체를 1로 줄입니다.

희망이 도움이됩니다.

감사합니다.

+1

그런데 11gR2 데이터베이스에서이 솔루션을 테스트했습니다. – IronDrake

+0

답장을 보내 주셔서 감사합니다. 귀하가 말한 것에 따라 유망 해 보였습니다. 질의를 실행했을 때 매우 이상한 숫자를주었습니다 (102 명의 형제가있는 고객!) 내가 아는 것은 옳지 않습니다. REL_CODE 및 REL_END는 '부모 관계'만 유지해야하지만 실제로는 클라이언트의 모든 관계를 보유하고있는 표 B와 관련이 있습니다. – bawpie

+1

테스트 케이스를 첨부 할 수 있습니까? – IronDrake

관련 문제