访问SQL:子查询到IIF?

时间:2012-11-16 20:25:00

标签: sql vba ms-access subquery

我有以下查询可以正常工作:

SELECT NomComplet, IIF(Count(FS3.Index) = 0, '0 (RAS)', Count(FS3.Index))  
 FROM ControleAcces INNER JOIN ( 
     Employes LEFT JOIN ( 
         SELECT FS1.Index, FS1.OTP, FS1.OTP, FS1.Axe, FS1.FaitSaillant, FS1.Utilisateur, FS2.DateInsertion  
         FROM FaitsSaillants AS FS1 INNER JOIN ( 
             SELECT Axe, Index, Max(FaitsSaillants.DateInsertion) AS DateInsertion  
             FROM FaitsSaillants  
             WHERE DateValue(DateInsertion) > #2010-01-01#  
             AND DateValue(DateInsertion) < #2011-12-31#  
             GROUP BY Axe, Index 
         ) AS FS2  
         ON (FS1.DateInsertion = FS2.DateInsertion  
         AND FS1.Index = FS2.Index)  
         WHERE FS1.Axe = 'Project' AND FS2.Axe = 'Project' 
     ) AS FS3  
     ON Employes.CIP = FS3.Utilisateur 
 )  
 ON ControleAcces.Valeur = Employes.CIP
 GROUP BY NomComplet
 ORDER BY NomComplet

不要完全理解它,我想要它在第一行编辑我的IIF条件。实际上,条件没有做太多,它检查查询返回多少FS3.Index并连接(RAS)如果它是0.但是,实际上,我希望它检查{{中是否有任何行1}} FaitsSaillants。如果Count()是&gt; 0,然后满足条件。

我可以在IIF段中执行子查询,例如Axe = 'RAS'吗?如果结果为0,那么我将SELECT COUNT(Index) FROM FaitsSaillants WHERE Axe = 'RAS' AND Utilisateur = FS1.Utilisateur添加到我的第二个字段的结果中。如果没有,则保持RAS

我尝试过,虽然语法正确,但问题是它无法检查Count(FS3.Index)条件,因为FS1在主查询中。但是,我必须检查一下,因为这是确保我正在寻找正确的东西的唯一方法:无论我是在主查询还是在子查询中,它都必须是相同的Utilisateur = FS1.Utilisateur

修改

以下是我在下面的答案/评论中尝试的简短版本。

Utilisateur

我仍然收到有关FS2.AxeCount的错误,该错误不属于聚合函数(iff)。

我也试过这个:

SELECT NomComplet, IIf(FS2.AxeCount > 0, "0 (RAS)", count(FS3.index))
FROM ControleAcces INNER JOIN (Employes LEFT JOIN (SELECT FS2.AxeCount, FS1.Index, FS1.OTP, FS1.OTP, FS1.Axe, FS1.FaitSaillant, FS1.Utilisateur, FS2.DateInsertion  
         FROM FaitsSaillants AS FS1 INNER JOIN ( 
             SELECT Axe, Index, Max(FaitsSaillants.DateInsertion) AS DateInsertion, SUM(IIf(Axe = 'RAS', 1, 0)) As AxeCount  
             FROM FaitsSaillants 
             GROUP BY Axe, Index 
         ) AS FS2  
         ON (FS1.DateInsertion = FS2.DateInsertion  
         AND FS1.Index = FS2.Index)  
     )  AS FS3 ON Employes.CIP = FS3.Utilisateur) ON ControleAcces.Valeur = Employes.CIP
GROUP BY NomComplet;

2 个答案:

答案 0 :(得分:1)

我有点不清楚你想要在FaitsSaillants表中检查什么;你说:

  

我想检查一下FaitsSaillants中是否有任何行   Ax ='RAS'。如果Count()是&gt; 0,然后满足条件。

但你也说过:

  

类似SELECT COUNT(索引)FROM FaitsSaillants WHERE Ax =   'RAS'和Employes.CIP = FS3.Utilisateur

我的猜测是你的意思是SELECT COUNT(Index) FROM FaitsSaillants WHERE Axe = 'RAS',因为在第二个SQL语句中你加入了两个未在子查询的FROM子句中引用的表。

在IIF声明中使用DCount怎么样?

IIF(DCount("Index", "FaitsSaillants", "Axe='RAS'"), '0 (RAS)', Count(FS3.Index)) 

如果您的意思是SELECT COUNT(Index) FROM FaitsSaillants WHERE Axe = 'RAS',这应该有效,但如果您有其他想法,则需要修改。

虽然只是一个警告:我会尽量使用“域”功能(DCount,DLookup等),因为它们很慢。

顺便说一下,我相信你也可以在你的IIF语句中使用子查询(它是否给你一个错误?它似乎对我有用):

IIF((SELECT COUNT(*) FROM FaitsSaillants WHERE Axe = 'RAS'), '0 (RAS)', Count(FS3.Index)) 

确保将子查询放在括号中。

答案 1 :(得分:1)

如果没有相应的记录,

FS3.Index为NULL,因为LEFT JOIN。不会测试

IIf(IsNull(FS3.Index), ..., ...)

......够了吗?我不确定,因为还涉及其他条件和联接。


更新(重新发布评论)

我们可以从最里面的嵌套SELECT(FS2)中获得所需的计数(AxeCount):

SELECT
    Axe, Index, Max(FaitsSaillants.DateInsertion) AS DateInsertion,
    SUM(IIf(Axe = 'RAS', 1, 0)) As AxeCount
FROM FaitsSaillants  
...

通过将中间结果包含在中间SELECT(FS3)的选择列表中,必须将此中间结果传递给最外面的SELECT:

SELECT FS2.AxeCount, FS1.Index, ...

最外面的SELECT有一个GROUP BY子句。在这种情况下,选择列表的所有字段必须包含在GROUP BY子句中,或者必须包含在聚合函数中。 GROUP BY子句按照此子句中列出的字段对行进行分组。这通常会减少行数,因为它们的组字段中类似的几行会被压缩形成一行。这意味着必须将选择列表的剩余字段的值(不在组字段中)组合在一起。这就是聚合函数的作用。聚合函数是

  • 平均(<平均)
  • 计数
  • 首先,最后
  • 最小,最大(最小,最大)
  • StDev,StDevP(标准差)
  • 萨姆
  • Var,VarP(方差)

请参阅SQL Aggregate Functions (Access)

现在,我们可以在最外面的选择列表中添加它

IIf(SUM(FS2.AxeCount) > 0, ..., ...)