0

私は2つのテーブルを持っています:

  Questions table with Question ID

パーツテーブル:

   Question ID
   Part ID
   BAllPartsRequired

ユーザーはいくつかのパーツを選択し(または何も選択しない場合もあります)、選択したものに応じて特定の質問が表示されます。

3つのシーンリオの2つのテーブルを結合したいのですが、すべて1つのクエリで実行します。各シーンリオを個別に書くことはできますが(編集はできると思いましたが、シナリオ3は、パーツテーブルで見つかったものをすべて選択する必要がある場合は作業できません)、1つのクエリですべてを取得する方法を理解できません(実行しました)以前は似ていましたが、方法を思い出せません)。

  1. その質問のパーツテーブルにパーツが存在しない場合は、質問を再実行してください

  2. 選択したパーツがパーツテーブルの戻り質問に存在する場合(つまり、ユーザーが1つのパーツを選択し、5つのパーツがその質問に関連付けられている場合、質問は一致して返されます)。BAllPartsRequired = false

  3. ユーザーがパーツを選択し、すべてのパーツが質問に関連付けられている場合、質問は返されますが、すべてのパーツがユーザーによって選択されていない場合、質問は返されません(つまり、ユーザーが3つのパーツを選択し、テーブルに4つのパーツがある場合、ユーザーは質問を参照してください。ただし、ユーザーが4つの部分すべてを選択すると、質問が表示されます)。BAllPartsRequired = true

私は高度なSQLプログラマーですが、これは私を理解していません。以前にこれを行ったことがあることはわかっていますが、1つのクエリで機能させるにはどうすればよいですか、ネストされた結合、左結合、whereステートメントのケースなどを実行しますか?そうしないと。

サンプルデータ:

Question Form Association:          
NFormAssociationID  NQuestionID FormType    
1   1   PAEdit  
2   2   PAEdit  
3   3   PAEdit  
4   4   PAEdit  




Question Part Form Association Table:           
ID  NFormAssociationID  PartNumber  BAllPartsRequired
1   1   1   0
2   2   2   1
3   2   3   1

新しいパーツテーブルを追加せずにクエリを実行します。

Select ROW_NUMBER() OVER(ORDER BY QL.NOrderBy) AS RowNumber,
QL.NQuestionID, QL.FieldName, QL.Question, QL.BRequired, QFL.FormFieldType, QFL.SingleMultipleSM, 
QFL.CSSStyle
FROM dbo.QuestionFormAssociation QA WITH (NOLOCK)
INNER JOIN dbo.QuestionLookup QL WITH (NOLOCK) ON QA.NQuestionID = QL.NQuestionID
INNER JOIN dbo.QuestionFieldTypeLookup QFL WITH (NOLOCK) ON QL.NFieldTypeID = QFL.NFieldTypeID
WHERE QA.BActive = 1 AND QL.BActive = 1 AND QFL.BActive=1
AND QA.FormType = 'PAEdit'
ORDER BY QL.NOrderBy

新しいテーブルを使用した単純なクエリ

Select ID
    FROM dbo.QuestionPartFormAssociation 
    WHERE BAllPartsRequired = 1 
    AND PartNumber IN ('1', '2') --'1', '2', '3')   
4

1 に答える 1

1

いくつかの基準に基づいて、適格な質問を見つけようとしているようです。

この状況では、最初に質問レベルで要約してから、それらの要約にロジックを適用するのが最善です。次に例を示します。

select q.questionid
from (select q.questionid,
             max(case when qp.questionid is null then 1 else 0 end) as HasNoParts,
             sum(case when qp.partid in (<user parts>) then 1 else 0 end) as NumUserParts,
             count(qp.questionid) as NumParts,
             max(qp.AllPartsRequired) as AreAllPartsRequired
      from question q left outer join
           questionpart qp
           on q.questionid = qp.questionid
      group by q.questionid
     ) q
 where HasNoParts = 1 or                                   -- condition 1
       AreAllPartsRequired = 0 and NumUserParts > 0 or     -- condition 2
       AreAllPartsRequired = 1 and NmUserParts = NumParts  -- condition 3

ロジックを明確にするために、テーブル名と列名を簡略化しました。

OPからの完全な回答で更新:

Select ROW_NUMBER() OVER(ORDER BY QL.NOrderBy) AS RowNumber,
QL.NQuestionID, QL.FieldName, QL.Question, QL.BRequired, QFL.FormFieldType, QFL.SingleMultipleSM, 
QFL.CSSStyle
FROM dbo.QuestionFormAssociation QA WITH (NOLOCK)
INNER JOIN dbo.QuestionLookup QL WITH (NOLOCK) ON QA.NQuestionID = QL.NQuestionID
INNER JOIN dbo.QuestionFieldTypeLookup QFL WITH (NOLOCK) ON QL.NFieldTypeID = QFL.NFieldTypeID
INNER JOIN (
    select q.NFormAssociationID,
    max(case when qp.NFormAssociationID is null then 1 else 0 end) as HasNoParts,
    sum(case when qp.PartNumber in ('1','2','3') then 1 else 0 end) as NumUserParts,
    count(qp.NFormAssociationID) as NumParts, 
    qp.BAllPartsRequired
    from QuestionFormAssociation q 
    left outer join QuestionPartFormAssociation qp on q.NFormAssociationID = qp.NFormAssociationID      
        AND QP.BActive = 1  
    WHERE Q.FormType = 'PAEdit' 
    AND Q.BActive = 1   
    group by q.NFormAssociationID, qp.BAllPartsRequired

) QSUB ON QA.NFormAssociationID = QSUB.NFormAssociationID
WHERE QA.BActive = 1 AND QL.BActive = 1 AND QFL.BActive=1
AND (
    QSUB.HasNoParts = 1                                                     -- condition 1
    OR (QSUB.BAllPartsRequired = 0 and QSUB.NumUserParts > 0)               -- condition 2
    OR (QSUB.BAllPartsRequired = 1 and QSUB.NumUserParts = QSUB.NumParts)   -- condition 3
)
ORDER BY QL.NOrderBy
于 2012-08-09T19:27:38.383 に答える