【问题标题】:Access Query mysteriously omitting records访问查询神秘地省略记录
【发布时间】:2019-08-23 16:01:01
【问题描述】:

我有一个 MS Access 联系人和通信数据库,其中包含一个“联系人”表(姓名、电话、电子邮件等)和一个“呼叫”表(联系人、传入/传出、时间、媒体、便笺等)。 )。这些表在 Contacts.ID = Calls.Contact 上链接

例如:

NAME            NUMBER      EMAIL
Michaelangelo   123-4567    M@TMNT.com
Donatelo        123-4567    d@TMNT.com
Leonardo        123-4567    L@TMNT.com
Raphael         123-4567    R@TMNT.com

CONTACT         TIME        IN/OUT
Michaelangelo   1/1/2019    Outgoing
Michaelangelo   1/15/2019   Incoming
Michaelangelo   2/1/2019    Outgoing
Michaelangelo   3/1/2019    Outgoing
Leonardo        1/1/2019    Outgoing
Leonardo        2/1/2019    Outgoing
Michaelangelo   3/15/2019   Incoming

我正在尝试构建一个查询来报告所有联系人信息(就像直接打开表时一样),但有一个字段显示最近的传入和传出通信。

所以,对于上述数据:

NAME            LAST OUT    LAST IN     NUMBER      EMAIL
Michaelangelo   3/1/2019    3/15/2019   123-4567    M@TMNT.com
Donatelo                                123-4567    d@TMNT.com
Leonardo        2/1/2019                123-4567    L@TMNT.com
Raphael                                 123-4567    R@TMNT.com

因此,结果将独立识别传入和传出类型的通信记录的最新日期,并在尚不存在此类通信类型的情况下返回 [nulls]。

我有一个查询主要是有效的。然而,它似乎神秘地省略了“呼叫”中没有记录的某些记录。请注意,并非所有此类记录。

我现有的、有问题的代码如下所示。我还尝试在 JOINS 中移动 WHERE 语句(在 ON 之前);我尝试使用 Calls.Time IS NULL OR Calls_1.Time IS NULL OR ... 打开 WHERE 语句 ,以及 WHERE 语句的其他几个版本。

这是现有的查询:

SELECT Contacts.Name_First, Contacts.Name_Last, Max(Calls.Time) AS [Last Incoming], Max(Calls_1.Time) AS [Last Outgoing]
FROM (Contacts 
LEFT OUTER JOIN Calls AS Calls_1 ON Contacts.ID = Calls_1.Contact ) 
LEFT OUTER JOIN Calls ON Contacts.ID = Calls.Contact 
WHERE (
(((Calls.Outgoing_Incoming)="Incoming")  OR  Calls.Outgoing_Incoming IS NULL)
AND 
(((Calls_1.Outgoing_Incoming)="Outgoing") OR Calls_1.Outgoing_Incoming IS NULL)
)
GROUP BY Contacts.Name_First, Contacts.Name_Last;

完整的“联系人”表有 361 条记录。预期的结果是返回所有的 361 记录,无论它们是否在 'Calls' 中有对应的记录。

实际上只返回了 208 条记录。其中许多没有相应的“呼叫”记录,告诉我 OR NULL 语句至少部分有效。我找不到任何一致的区别被省略的记录和返回的记录。

【问题讨论】:

  • 样本数据、期望的结果以及查询应该做什么的解释会有所帮助。
  • 谢谢@GordonLinoff,完成。

标签: sql ms-access


【解决方案1】:

在执行JOIN 之前 进行聚合。那么你只需要聚合一次:

SELECT c.Name_First, c.Name_Last, ca.Last_Incoming, ca.Last_Outgoing
FROM Contacts as c LEFT OUTER JOIN
     (SELECT Contact,
             MAX(IIF(Outgoing_Incoming IS NULL OR Outgoing_Incoming = "Incoming", Time, NULL)) as Last_Incoming,
             MAX(IIF(Outgoing_Incoming IS NULL OR Outgoing_Incoming = "Outgoing", Time, NULL)) as Last_Outgoing,
      FROM Calls 
      GROUP BY Contact
     ) as ca
     ON c.ID = c.Contact ;

【讨论】: