在已分组的查询上使用“总计”功能

时间:2013-05-25 19:34:19

标签: ms-access

在查询中使用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来确定它是否是第一个查询的第一个。但是,每次表单刷新或调用requery时,每一行的条件格式都会触发另一个dlookup,然后引用每行重新计算新排名的第一个查询!

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

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

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

一如既往,非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

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

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次。然后,如果我使用Value = DMin("CalculatedRank", "qryTable1Ranked")在[CalculatedRank]文本框中添加条件格式,那么我的函数将被调用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 SourceqryTable1Ranked更改为Table1(基表),我发现我可以将其减半(至8次)并更改[CalculatedRank]文本框Control Source =CalculateRank([ID])(仍然使用上一次调整中的技巧)。

认为可能就像创建临时表一样好,或者在基表中持久存在CalculatedRank(可能还有一个“IsMin”标志)。