使用IIf将SELECT嵌套在查询中

时间:2017-09-14 21:22:55

标签: sql ms-access nested iif

我的任务是在MS Access中构建一个查询。

重要

表和数据都是示例。我不能发布实际数据,因为它是PII。我尽力创建我的数据显示的模型。假设拼写不是问题。

我有一张包含人们信息的表tblMemberInfo。我正在创建一份报告,该报告会按tblMemberInfo.MemberID列出每个成员,然后为每个DateCompleted列出EventID。这目前的工作原理。但是,我们需要根据tblMemberInfo.PositionID加入tblPositionExemptions.PositionID时引用的工作职位来证明他们是否获得豁免。

tblMemberCompletionDates

 MemberID  | EventID | DateCompleted
-----------+---------+--------------
1234567890 | English |   1/1/2017
1234567890 |  Math   |   5/8/2017
2345678901 | English |   1/1/2017
2345678901 |  Math   |   9/5/2017

tblMemberInfo

 MemberID  | PositionID | more... (like First/Last Name)
-----------+------------+-------------------------------
1234567890 |      1     |   
1234567890 |      1     |    
2345678901 |      2     |    
2345678901 |      2     |    

tblPositionExemptions

 PositionID  | EventID
-------------+--------
      1      | English 
      1      | History
      1      | Science  
      2      |  Math

这是我正在寻找的预期输出。

qryGetMemberCompletionDates

 MemberID  | EventID | DateCompleted
-----------+---------+--------------
1234567890 | English |   EXCLUDED
1234567890 |  Math   |   5/8/2017
2345678901 | English |   1/1/2017
2345678901 |  Math   |   EXCLUDED

此查询显然会返回tblMemberCompletionDates中的所有内容。但就像我说的那样我需要显示“排除”。

SELECT 
    tMCD.MemberID, tMCD.EventID, tMCD.DateCompleted
FROM 
    tblMemberCompletionDates as tMCD

所以我在查询中创建了这个列,但是由于查询仅为4836行,所以它很慢。还有大约200名成员,每人大约有45名成员。如果我将EventID列设置为仅显示与英语相同的列,则需要大约10秒才能完成为每个成员返回200行。简单的数学运算使得运行完整查询大约需要500秒。

DateDue: IIf([qryGetMemberCompletionDates].[EventID]=
             DLookUp("[EventID]","tblPositionExemptions",
                     "PositionID= '" & DLookUp("[PositionID]",'tblMemberInfo', "MemberID= '" 
                                               & [qryGetMemberCompletionDates].[MemberID] & "'") & "'"),
             "EXCLUDED",[qryGetMemberCompletionDates].[DateCompleted])

有没有办法让它读得更快?我倾向于想要做这样的伪代码。

SELECT 
    MemberID, EventID, 
    IIF([qryGetMemberCompletionDates].[EventId] = 
             (SELECT EventID FROM tblPositionExemptions 
              WHERE EventID = "'" & qryGetMemberCompletionDates].[EventId] & "'" 
                AND PositionID = (SELECT PositionID FROM tblMemberInfo 
                                  WHERE MemberID = "'" & [qryGetMemberCompletionDates].[EventId] & "'")),
              "EXCLUDED", [qryGetMemberCompletionDates].[DateCompleted]) AS DueDate

FROM qryGetMemberCompletionDates AS qGMCD
GROUP BY qGMCD.MemberID, qGMCD.EventID, 
         IIf([qryGetMemberCompletionDates].[EventId] = 
              (SELECT EventID FROM tblPositionExemptions 
               WHERE EventID = "'" & qryGetMemberCompletionDates].[EventId] & "'" 
              AND PositionID = (SELECT PositionID FROM tblMemberInfo 
                                 WHERE MemberID = "'" & [qryGetMemberCompletionDates].[EventId] & "'")),
              "EXCLUDED",[qryGetMemberCompletionDates].[DateCompleted])

2 个答案:

答案 0 :(得分:1)

考虑使用带有条件聚合的LEFT JOIN DateCompleted 字段:

SELECT tMCD.MemberID, tMCD.EventID, 
       MAX(IIf(tMCD.EventID=tPE.EventID,'EXCLUDED',tMCD.DateCompleted)) AS DateCompleted
FROM (tblMemberCompletionDates AS tMCD 
LEFT JOIN tblMemberInfo AS tMI 
  ON tMCD.MemberID = tMI.MemberID) 
LEFT JOIN tblPositionExemptions AS tPE 
  ON tMI.PositionID = tPE.PositionID
GROUP BY tMCD.MemberID, tMCD.EventID;

要绘制图表,蓝色代表IIF()条件,常用黑色箭头为LEFT JOIN。所以你要同时检查两种情况。

SQL Query Diagram

答案 1 :(得分:0)

先加入联接:

在tblPostioinExemptions上选择qGMCD。,tblMemberInfo。,tblPositionExemptions。*来自tblPostioinExemptions内连接(tblMemberInfo内连接qryGetMemberCompletionDates为qGMCD.EventID = tblMemberInfo.MemberID上的qGMCD)...

如果内部,左侧,右侧连接的组合未能为您提供正确的记录,请执行单独的查询并将结果与​​Union查询结合。

运行您的IIF并对加入/联合数据的结果进行分组。您希望所有联接(如果可能的话,所有组)都使用索引数据。

或者,如果您要自动执行此操作并完成更多工作,请创建一个临时分组表并在其上运行您的IIF。