2016-07-18 13 views
1

私はこの問題に悩まされています。親子関係と親子関係のペアごとに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

    要件は、我々はそれぞれのペア(ジョン、マイク)(ジョン、ナンシー)(ピーター、マイク)(1つのレコードを含める必要があり を意味し、ユーザーの各ペアで1人の関係を取得することですその実際に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は、各ペアに対して1つの行のみを返します。

    エントリが1つしかない(ペアではない)場合、または2つ以上のエントリがある場合、クエリは正しく動作します。このような結果セットをスキップ

    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

    私は実際に関係テーブルのレコードを1つだけ保存すると思います。 MikeとPeterのレコードを既に持っているので、1239、Mike、Peter、Siblingのレコードを追加しないでください。次に、親子関係の場合、親が常に「親」列にあり、「子」が従属列にあると仮定することができます。

    だから、基本的にあなたがテーブルに持っているだろうすべては次のようになります。

    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

    こんにちはJacob、助けてくれてありがとう 私は他の方法でデータを保存したいと思っていますが、私たちはそのフォーマットのデータを受け取ります。 私の目標は、ペアごとに1つのレコードのみを取得することです。テーブルには数千のレコードが含まれているため、ペアごとに1つのクエリを作成するほど簡単ではありません。私は1つのレコードを取得する必要がある場合、あなたのソリューションは素晴らしいだろうが、私の場合は、テーブルの1つのレコードよりも一般的です。 ありがとうございました – pmorales