根据ID

时间:2016-07-05 21:00:19

标签: ms-access

我有一个演讲者表,可以存储数据:

SessionID  ||  SpeakerID
1          ||  54
1          ||  897
2          ||  63
2          ||  897
2          ||  444

我正在尝试创建一个查询,显示数据,使其每个SessionID返回1行,每个SpeakerID都有一列,如下所示:

SessionID  ||  SpeakerID 1 ||  SpeakerID 2 ||  SpeakerID 3
    1      ||  54          ||  897         ||
    2      ||  63          ||  897         || 444

我看到一个老帖子解决了这个问题,并且已经玩了很长时间但却无法使用它。 Access Row Data to Columns Based Off ID 结果我看起来像这样:

SessionID || SpeakerID 2 || SpeakerID 3
1         || 897         ||
2         ||             || 444
你能告诉我我错过了什么吗?很明显,它正在跳过我的一些演讲者而只展示最后一些,但我不确定如何得到我需要的结果。删除“Last()”只会引发错误。

TRANSFORM Last(SpeakersCustomerSort_qry.ID) AS SpeakerDetails
SELECT SpeakersCustomerSort_qry.SessionID
FROM SpeakersCustomerSort_qry
GROUP BY SpeakersCustomerSort_qry.SessionID
PIVOT "Speaker " & (DCount("[SessionID]","[SpeakersCustomerSort_qry]","SessionID=" & [SessionID])+1);

1 个答案:

答案 0 :(得分:1)

如果您的表名为Speakers,那么您要查找的SQL是:

TRANSFORM Last(Speakers.SpeakerID) AS SpeakerDetails
SELECT Speakers.SessionID
FROM Speakers
GROUP BY Speakers.SessionID
PIVOT "Speaker " & (
  DCount("[SpeakerID]", 
         "[Speakers]", 
         "[SessionID] = " & [SessionID] & " AND [SpeakerID] < " & [SpeakerID]
  ) + 1
);

这是如何工作的?

统计发言人

首先,可能有助于弄清楚DCount表达式正在做什么。尝试将其粘贴到新查询的SQL视图中(同样,对于名为Speakers的表):

SELECT Speakers.SessionID, Speakers.SpeakerID, 
  "Speaker " & (
    DCount("[SpeakerID]", 
           "[Speakers]", 
           "[SessionID] = " & [SessionID] & " AND [SpeakerID] < " & [SpeakerID]
  ) + 1) AS SpeakerNumber
FROM Speakers;

检查结果时,您应该看到:

SessionID | SpeakerID | SpeakerNumber
--------- | --------- | -------------
        1 |        54 | Speaker 1
        1 |       897 | Speaker 2
        2 |        63 | Speaker 1
        2 |       897 | Speaker 3 
        2 |       444 | Speaker 2

SpeakerNumber表达式对Speakers表中的每一行执行以下计算:

  • 查找SpeakersSessionID与当前SessionID匹配的所有行...
  • AND SpeakerID小于当前的SpeakerID
  • 计算此集合中SpeakerID的值(=行数)
  • 1添加到该计数
  • 使用Speaker
  • 作为前缀

让我们尝试Speakers中的第一行,其中当前SessionID1,当前SpeakerID54

  • 查找SessionID = 1

    所在的行集
    SessionID | SpeakerID
    --------- | ---------
            1 |        54
            1 |       897
    
  • 在这些内容中,找到SpeakerID < 54没有行的行集
  • 计算此集合中的行数:0
  • 0 + 1 = 1
  • 前缀:Speaker 1

我会留给读者来处理表格中其余行的算法,但希望您现在可以看到SpeakerNumber中这些值的来源。

所以我们这里有一个方法以SpeakerID 的升序对每个Session的SpeakerID进行计数,从1开始计数。

返回交叉表

想象一下,将上面的3列结果与其进行交叉制表,每个值SpeakerNumber作为列标题,每个值SessionID作为行标题,以及相应的一些摘要每个单元格中SpeakerIDs。这就是顶部的交叉表SQL。

最后一个问题是:我们如何总结与SpeakerIDsSpeakerNumber的每个组合相对应的SessionID?这就是Last([SpeakerID])聚合函数的用武之地。它只是说:

  • 针对SpeakerNumberSessionID ...
  • 的每个组合
  • 找到所有匹配的SpeakerIDs
  • 返回该列表中的最后一个

由于每个SpeakerNumber / SessionID组合仅匹配单个SpeakerID,因此这只会为我们提供相应SpeakerID的值。在这种情况下,使用First()聚合函数会得到相同的结果。

您必须在交叉制表中使用某些类聚合函数,因为理论上每个因子组合可能有多个匹配值(这就是为什么Access在Last()功能已被删除。)