0

我有 2 张桌子:

  Questions table with Question ID

零件表:

   Question ID
   Part ID
   BAllPartsRequired

用户将选择一些部分(或可能不选择),并根据选择的内容显示某些问题。

我想为 3 个场景加入 2 个表,但在 1 个查询中全部完成。我可以单独编写每个场景(编辑我认为我可以,但场景 3 我无法开始工作,它需要选择部分表中的所有内容)但无法弄清楚如何在 1 个查询中获取所有内容(我已经完成以前有类似的东西,但不记得如何)。

  1. 如果该问题的零件表中不存在任何零件,则重新提出该问题

  2. 如果选择的任何部分存在于部分表返回问题中(即用户选择 1 个部分并且 5 个部分与该问题相关联,则该问题将匹配并被返回)。BAllPartsRequired = 假

  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 回答