2016-07-18 2 views
1

이 문제로 인해 어려움을 겪었습니다.부모 - 자식 관계와 자녀 - 부모 관계의 각 쌍에 대해 하나의 행을 선택하십시오.

종속성 테이블으로 작업하고 있습니다.

간단한 예를

ID, parent, dependent, relationship 
1234, John, Mike, Parent 
1235, Mike, John, Child 
1236, Nancy, John, Spouse 
1237, John, Nancy, Spouse 
1238, Peter, Mike, Sibling 
1239, Mike, Peter, Sibling 

이 의존성 중 일부는 "거울 종속성"(같이 1234 및 1235)

  • 요한이
  • 마이크 아이입니다 마이크의 부모입니다입니다 John of

요구 사항은 우리가 각 쌍 당 하나 개의 기록 (요, 마이크), (요, 낸시)(피터, 마이크)를 (포함해야 의미, 사용자의 각 쌍에 의해 하나 개의 관계를 검색하는 것입니다 그 사실 대신 이름의 person_key 때문에)

1234, John, Mike, Parent 
1237, John, Nancy, Spouse 
1238, Peter, Mike, Sibling 

또는

1235, Mike, John, Child 
1236, Nancy, John, Spouse 
1239, Mike, Peter, Sibling 

어떤 중복 될 수 있지만, 예를 위해 내가 이름을 사용해서는 안 미러링 레코드를 건너 뛰기 위해 SQL을 사용하는 방법에 대한 아이디어가 있습니까?

+0

당신이 (구분 기호가하는 것처럼 쉼표로 표준 분할 기능) 먼저 테이블을 분할해야, 결과 집합을 것이다 건너 뛰는, 그런 다음 분할을 사용하여 일치 항목을 검색 한 다음 일치 항목 중 첫 번째 항목 만 선택하거나 일치하지 않는 항목 만 선택하십시오 (가능한 경우). – ZLK

답변

0

샘플 데이터

DECLARE @Dependencies TABLE 
([ID] int, [parent] varchar(50), [dependent] varchar(50), [relationship] varchar(50)); 

INSERT INTO @Dependencies 
([ID], [parent], [dependent], [relationship]) 
VALUES 
(1234, 'John', 'Mike', 'Parent'), 
(1235, 'Mike', 'John', 'Child'), 
(1236, 'Nancy', 'John', 'Spouse'), 
(1237, 'John', 'Nancy', 'Spouse'), 
(1238, 'Peter', 'Mike', 'Sibling'), 
(1239, 'Mike', 'Peter', 'Sibling'); 

쿼리

계산 MIN(parent, dependent)MAX하고 당신이 할 수있는 함께 그룹을.

SELECT 
    ID 
    ,CASE WHEN [parent] < [dependent] THEN [parent] ELSE [dependent] END AS MinRelationship 
    ,CASE WHEN [parent] > [dependent] THEN [parent] ELSE [dependent] END AS MaxRelationship 
    ,[relationship] 
FROM @Dependencies 
; 

결과

+------+-----------------+-----------------+--------------+ 
| ID | MinRelationship | MaxRelationship | relationship | 
+------+-----------------+-----------------+--------------+ 
| 1234 | John   | Mike   | Parent  | 
| 1235 | John   | Mike   | Child  | 
| 1236 | John   | Nancy   | Spouse  | 
| 1237 | John   | Nancy   | Spouse  | 
| 1238 | Mike   | Peter   | Sibling  | 
| 1239 | Mike   | Peter   | Sibling  | 
+------+-----------------+-----------------+--------------+ 

나머지는 당신이 선택하려는 각 쌍에서 한 행에 따라 달라집니다. 예를 들어, 가장 작은 행 ID을 선택하려고 할 수 있습니다. CTE_MinMax은 위의 간단한 쿼리입니다. CTE_rn은 쌍으로 분할되고 ID으로 정렬 된 각 행에 숫자를 추가합니다. 마지막 SELECT은 각 쌍마다 하나의 행만 반환합니다.

한 쌍의 항목 만 있거나 두 개 이상의 항목이있는 경우 쿼리가 올바르게 작동합니다. 이것은 그렇게 쉬운 일이 아닙니다처럼

WITH 
CTE_MinMax 
AS 
(
    SELECT 
     ID 
     ,CASE WHEN [parent] < [dependent] THEN [parent] ELSE [dependent] END AS MinRelationship 
     ,CASE WHEN [parent] > [dependent] THEN [parent] ELSE [dependent] END AS MaxRelationship 
     ,[relationship] 
    FROM @Dependencies 
) 
,CTE_rn 
AS 
(
    SELECT 
     ID 
     ,MinRelationship 
     ,MaxRelationship 
     ,relationship 
     ,ROW_NUMBER() OVER (PARTITION BY MinRelationship, MaxRelationship ORDER BY ID) AS rn 
    FROM CTE_MinMax 
) 
SELECT 
    ID 
    ,MinRelationship 
    ,MaxRelationship 
    ,relationship 
FROM CTE_rn 
WHERE rn = 1 
; 

결과

+------+-----------------+-----------------+--------------+ 
| ID | MinRelationship | MaxRelationship | relationship | 
+------+-----------------+-----------------+--------------+ 
| 1234 | John   | Mike   | Parent  | 
| 1236 | John   | Nancy   | Spouse  | 
| 1238 | Mike   | Peter   | Sibling  | 
+------+-----------------+-----------------+--------------+ 
+0

아이디어를 제공해 주셔서 감사합니다. 사례를 통해 최소 및 최대 계산으로 그룹화하고 필요한 항목을 정확히 검색 할 수 있습니다. 답변을 대단히 감사합니다. – pmorales

+0

안녕하십니까. –

0

나는 실제로 관계에 대한 테이블에 하나의 레코드 만 저장한다고 생각합니다. Mike, Peter, Sibling의 1239 년 기록을 추가하지 않을 것입니다. 이미 Mike와 Peter에게 기록을 남기고 있기 때문입니다. 그런 다음 부모/자식 관계의 경우 부모가 항상 "부모"열에 있고 "자식"이 종속 열에 있다고 가정 할 수 있습니다.

그래서 기본적으로 모든 당신이 될 것 테이블에있는 것입니다 : 그래서

1234, John, Mike, Parent 
1237, John, Nancy, Spouse 
1238, Peter, Mike, Sibling 

을 당신이 뭔가를 할 것 마이크의 부모를 찾고 있다면 : 당신이 찾고있는 경우

select * from table where dependent = 'Mike' and relationship = 'Parent' 

존의 배우자를위한 :

select * from table where (parent = 'John' or dependent = 'John') and relationship = 'Spouse' 

당신이 피터스 형제를 찾고 있다면 :

select * from table where (parent = 'Peter' or dependent = 'Peter') and relationship = 'Sibling' 

어쨌든 접근 방식은 "미러 레코드"를 건너 뛰는 것보다 훨씬 간단하게 쿼리를 작성합니다.

+0

안녕하세요 제이콥, 도와 줘서 고마워. 나는 다른 방식으로 데이터를 저장하고 싶지만 그 형식으로 데이터를 받는다. 내 목표는 한 쌍당 하나의 레코드를 검색하는 것입니다. 테이블에는 수천 개의 레코드가 포함되어 있으므로 쌍당 하나의 쿼리를 만드는 것처럼 간단하지는 않습니다. 하나의 단일 레코드를 가져와야하는 경우 솔루션은 훌륭하게 작동하지만 내 경우는 테이블에있는 하나의 레코드보다 일반적입니다. 다시 한 번 감사드립니다. – pmorales

관련 문제