1

在使用查询等功能时,我在使用聚合函数时遇到了麻烦group by。我的聚合函数不是应用于整个查询记录集,而是仅应用于由查询性质确定的选择组。例如:

  Person      Date      Able
 -----------------------------
    A       21/05/13     0
    B       21/05/13    -1
    C       21/05/13    -1
    D       21/05/13     0

(grouped by Person, Date, Able)

应用聚合函数时:

 Person      Date      Able    Max(Able)   Min(Date)
----------------------------------------------------
   A       21/05/13     0          0       21/05/13  
   B       22/05/13    -1         -1       22/05/13
   C       23/05/13    -1         -1       23/05/13
   D       24/05/13     0          0       24/05/13

除非数据完全未分组,否则聚合函数将完全冗余。到目前为止,我一直在使用:

1) 使用另一个查询来引用初始查询并确定真正的聚合值。2) 让表单使用d函数 (dlookupdcount​​)调用第二个查询

在我的特定场景中,我有一个列表(与上面非常相似),需要按特定顺序(根据 ID 排名)呈现。但是,我在查询中使用表达式来定义不同类型的排名。这个想法是显示(使用条件格式)这个新排名中的第一条记录。如下图所示

 Person      Date      ID   CalculatedRank    
--------------------------------------------
   A       21/05/13     1        4
   B       21/05/13     2        2
   C       21/05/13     3        3
   D       21/05/13     4        1

理想情况下,我希望有另一列来确定哪个是第一个,这可以通过以下方式轻松实现:

first: [CalculatedRank] = Min( [CalculatedRank] )

但如上所述,Min() 并没有给我 1,它是在每行的基础上给我的(最小值并不总是 1,所以我不能任意设置)。

现在,我正在使用单独的查询来引用第一个查询,并根据计算出的排名对其进行排序。然后条件格式可以使用 dlookup 从第二个查询中确定它是否是第一个。但是,每次刷新表单或调用重新查询时,每一行的条件格式都会触发另一个 dlookup,然后引用为每一行重新计算新排名的第一个查询!

可以想象,延迟很明显,导致光标空闲 > 5 秒。我不太确定访问的内部机制,但是使用内置调试器,对 4 行记录集的重新查询导致我的CalculateRank()函数被调用 12 次,纯粹是通过调用第二个查询的条件格式。

总之,我已经将其范围缩小到需要单独的查询(因此需要 dlookup)才能正确使用聚合函数。如果我能够将所有内容保留在一个查询中,则条件格式不需要在另一个查询上使用 dlookup 来确定其状态。

我确信我不是唯一遇到此问题的人,并且想知道是否存在可以避免所有堆叠查询的解决方案。

与往常一样,非常感谢任何帮助!

4

1 回答 1

1

哇,我明白你的意思了!对于我的表 [Table1]

Person  Date        ID
------  ----------  --
A       2013-05-21   1
B       2013-05-21   2
C       2013-05-21   3
D       2013-05-21   4

和我的查询 [qryTable1Ranked]

SELECT Table1.*, CalculateRank([ID]) AS CalculatedRank
FROM Table1;

它在标准 VBA 模块中使用以下函数

Public Function CalculateRank(ID As Long) As Long
Dim r As Long
Select Case ID
    Case 1
        r = 4
    Case 4
        r = 1
    Case Else
        r = ID
End Select
CalculateRank = r
Debug.Print "x"
End Function

并返回

Person  Date        ID  CalculatedRank
------  ----------  --  --------------
A       2013-05-21   1               4
B       2013-05-21   2               2
C       2013-05-21   3               3
D       2013-05-21   4               1

当我只是双击查询以在数据表视图中打开它时,我的排名函数被调用 4 次,每行一次。

如果我基于该查询创建一个连续表单并打开该表单,我的函数将被调用 4 次。然后,如果我在 [CalculatedRank] 文本框中添加条件格式,Value = DMin("CalculatedRank", "qryTable1Ranked")那么我的函数会被调用 32 次!

我发现如果我添加一个名为 [txtMinCalculatedRank] 的不可见的未绑定文本框,我可以将其减少一半(至 16 次),请在表单后面使用以下代码...

Option Compare Database
Option Explicit

Private Sub Form_Load()
UpdateMinCalculatedRank
End Sub

Private Sub UpdateMinCalculatedRank()
Me.txtMinCalculatedRank.Value = DMin("CalculatedRank", "qryTable1Ranked")
End Sub

...并将条件格式规则更改为Value = [txtMinCalculatedRank].

我发现如果我将Record Source表单的从更改qryTable1RankedTable1(基表)并将Control Source[CalculatedRank] 文本框的更改为=CalculateRank([ID])(仍然使用上一个调整中的技巧),我可以再次将其减少一半(到 8 次) .

认为这可能与创建临时表或在基表中保留CalculatedRank(可能还有一个“IsMin”标志)一样好。

于 2013-05-26T13:38:31.787 回答