1

指定された値が別のテーブルにあるすべての指定された値に一致する1つのテーブルから結果をプルバックしたいと思います。私はこのようにそれを行うことができます:

SELECT * FROM Contacts 
WHERE 
EXISTS (SELECT 1 FROM dbo.ContactClassifications WHERE ContactID = Contacts.ID AND ClassificationID =  '8C62E5DE-00FC-4994-8127-000B02E10DA5')
AND EXISTS (SELECT 1 FROM dbo.ContactClassifications WHERE ContactID = Contacts.ID AND ClassificationID =  'D2E90AA0-AC93-4406-AF93-0020009A34BA')
AND EXISTS etc...

ただし、最大で約40個のEXISTS句を取得すると、それは失敗します。エラーメッセージは次のとおりです。「クエリプロセッサが内部リソースを使い果たし、クエリプランを作成できませんでした。これはまれなイベントであり、非常に複雑なクエリ、または非常に多くのテーブルやパーティションを参照するクエリでのみ発生します。クエリを簡略化してください。」

4

3 に答える 3

6

これの要点は

  • INステートメントから任意のGUIDを持つすべての連絡先を選択します
  • を使用しDISTINCT COUNTて、一致するGUIDの各連絡先IDのカウントを取得します
  • を使用して、ステートメントHAVINGに入力した一致するGUIDの量に等しい連絡先のみを保持しますIN

SQLステートメント

SELECT *
FROM   dbo.Contacts c
       INNER JOIN (
          SELECT c.ID
          FROM   dbo.Contacts c
                 INNER JOIN dbo.ContactClassifications cc ON c.ID = cc.ContactID
          WHERE  cc.ClassificationID IN ('..', '..', 38 other GUIDS)
          GROUP BY
                 c.ID
          HAVING COUNT(DISTINCT cc.ClassificationID) = 40
       ) cc ON cc.ID = c.ID

data.stackexchangeでスクリプトをテストします

于 2012-06-05T16:34:07.680 に答える
3

1つの解決策は、一致する連絡先がなければ分類が存在しないことを要求することです。これは二重否定です。

select  *
from    contacts c
where   not exists
        (
        select  *
        from    ContactClassifications cc
        where   not exists
                (
                select  *
                from    ContactClassifications cc2
                where   cc2.ContactID = c.ID
                        and cc2.ClassificationID = cc.ClassificationID
                )
        )

このタイプの問題は、関係除算として知られています。

于 2012-06-05T16:29:43.860 に答える
0
SELECT c.* 
FROM Contacts c
INNER JOIN 
 (cc.ContactID, COUNT(DISTINCT cc.ClassificationID) as num_class
  FROM ContactClassifications 
  WHERE  ClassificationID IN (....)
  GROUP BY cc.ContactID 
 ) b ON c.ID = b.ContactID
WHERE b.num_class = [number of distinct values - how many different values you put in "IN"]

SQLServer 2005以降を実行している場合は、とほぼ同じようにCROSS APPLY、おそらくより効率的に実行できます。

于 2012-06-05T16:32:29.837 に答える