2011-11-09 10 views
1

グループに関する情報を含むテーブルがあります。あるグループには何人ものメンバーがいます。グループ識別子と要素識別子があります。私は行グループ上のTSqlの等価性

@groupTableが既にデータベース

@inputDataに存在するデータの一例である与えられたセットがテーブルに存在するか否かを判断する一つの文でのことができるようにするためのデータをされたいというIそれはすでに今、私はセットの関係、groupIdentifierがどのtempGroupIdentifierに関連付けられている上映が表示されますクエリを実行したい@groupTable

declare @groupData table 
(
    groupIdentifier int, 
    elementIdentifier uniqueidentifier 
) 

insert into @groupData values 
(1, 'dfce40b1-3719-4e4c-acfa-65f728677700'), 
(1, '89e7e6be-cee8-40a7-8135-a54659e0d88c') 

declare @inputData table 
(
    tempGroupIdentifier int, 
    elementIdentifier uniqueidentifier 
) 

insert into @inputData values 
(42, 'dfce40b1-3719-4e4c-acfa-65f728677700'), 
(42, '89e7e6be-cee8-40a7-8135-a54659e0d88c'), 
(55, 'dfce40b1-3719-4e4c-acfa-65f728677700'), 
(55, '2395a42c-94f4-4cda-a773-221b26ea5e44'), 
(55, 'f22db9df-a1f4-4078-b74c-90e34376eff6') 

に存在するかどうかを確認したいです。一致するセットがない場合は、それも知る必要があります。

desired output: 
groupIdentifier, tempGroupIdentifier 
1, 42 
null, 55 

この問題にどのようにアプローチするかについてのご意見はありますか?

おそらく、行をピボットし、すべてのelementIdentifierを各グループの巨大な文字列に連結して、等価性のあるグループにすることはできますが、それは良い解決策のようには見えません。

+0

を設定しますか?私はここで本当の問題を抱えていますか? – Syska

+0

サンプルデータでは、値 'dfce40b1-3719-4e4c-acfa-65f728677700'が@inputdataテーブルに2回存在します。それは意図的でしたか? –

+0

@Syska:はい、しかし「行ごと」ではなく「行ごとに」 – gbn

答えて

1
SELECT 
     (
     CASE WHEN matchCount = gdCount AND matchCount = idCount 
      THEN groupIdentifier 
      ELSE NULL 
     END) groupIdentifier, 
     cj.tempGroupIdentifier 
    FROM 
    (
    SELECT gd.groupIdentifier, id.tempGroupIdentifier, COUNT(1) matchCount 
    FROM @groupData gd 
    CROSS JOIN @inputData id 
    WHERE id.elementIdentifier = gd.elementIdentifier 
    GROUP BY gd.groupIdentifier, id.tempGroupIdentifier) as cj 
    CROSS APPLY (SELECT COUNT(groupIdentifier) from @groupData gdca WHERE gdca.groupIdentifier = cj.groupIdentifier) as gdc(gdCount) 
    CROSS APPLY (SELECT COUNT(tempGroupIdentifier) from @inputData idca WHERE idca.tempGroupIdentifier = cj.tempGroupIdentifier) as idc(idCount) 
+0

wow。私はあなたが何をしているのか分かっていますが、そのCROSS JOINで拡大縮小するかどうかはわかりません。そして、カウントについてのFYI http://stackoverflow.com/questions/1221559/count-vs-count1/1221649#1221649 – gbn

+0

カウントマッチで事前にマッチすることで改善することができます。 (どちらのセットも、他のセットに存在しないアイテムを含んでいない場合、2つのセットは等しい - アイテム数が同じである)。エグゼクティブプランを見ていない – ImplexOne

+0

ありがとうございます。私が行った変更の1つは一致を返すだけなので、groupIdentifierを返し、 'matchCount = gdCountとmatchCount = idCount'を追加するためにケースを削除しました。それは、groupDataセットがより小さく(1行しか含まれていない)、入力グループが部分一致(groupDataからのセットに2つの行1が一致していた)だったときに重複を戻していたためです。 – BrandonAGr

3
SELECT DISTINCT 
    T1.tempgroupIdentifier, T2.GroupIdentifier 
FROM 
    (
    SELECT 
     COUNT(*) OVER (PARTITION BY tempgroupIdentifier) AS GroupCount, 
     ROW_NUMBER() OVER (PARTITION BY tempgroupIdentifier ORDER BY elementIdentifier) AS GroupRN, 
     tempgroupIdentifier, elementIdentifier 
    FROM 
     @inputData 
    ) T1 
    LEFT JOIN 
    (
    SELECT 
     COUNT(*) OVER (PARTITION BY GroupIdentifier) AS GroupCount, 
     ROW_NUMBER() OVER (PARTITION BY GroupIdentifier ORDER BY elementIdentifier) AS GroupRN, 
     GroupIdentifier, elementIdentifier 
    FROM 
     @groupData 
    ) T2 ON T1.elementIdentifier = T2.elementIdentifier AND 
         T1.GroupCount = T2.GroupCount AND 
         T1.GroupRN = T2.GroupRN 

編集:これはまた、与えられた中で同じ値に対処しますあなたは、テーブル(実および温度)の両方を持っている場合、左は仕事をする参加しないだろう

+1

theres欠けているtheres以外のコンマ:-)(他の5つの小さな編集を行うことなく、それを編集する方法があります) – Syska

+0

はい、私は制限がありません私自身の投稿 – gbn

+0

同じサイズのグループ間で部分一致がある場合、これはうまくいかないようです。@inputDataが '@inputData値 (42、 'dfce40b1-3719-4e4c-acfa-65f728677700')、 (42、 '89e7e6be-cee8-40a7-8135-a54659e0d88c')、 (55)に挿入するように変更された場合、 、 'dfce40b1-3719-4e4c-acfa-65f728677700')、 (55、 '2395a42c-94f4-4cda-a773-221b26ea5e44') 'クエリは不正確な結果を返します – BrandonAGr