如何为tblContacts表每行匹配tblCalls表的TOP 1记录?
解决每个联系人匹配单条通话记录的问题
我来帮你搞定这个问题!你的核心需求应该是为每个未归档(Archive=False)的联系人,获取其对应的某一条特定通话记录(比如最新的那条),而不是整个通话表的第一条记录,对吧?咱们一步步来解决:
为什么你原来的SQL没起作用?
你之前的SQL里,GROUP BY只是把所有字段完全相同的记录合并,根本没实现“按联系人分组取TOP1”的逻辑;直接加TOP 1的话,是对整个查询结果集取第一条,自然只能返回总计1条记录,完全不符合需求。
解决方案(以Access SQL为例,你的语法看起来是Access)
方法1:通过“最大通话时间”匹配最新记录
如果你的需求是取每个联系人的最新通话记录,可以先通过子查询找出每个联系人的最晚通话时间,再关联回去找到对应的那条记录:
SELECT c.ID AS CallID, c.[Call Time], c.NextContact, c.Subject, c.Notes, [First Name] & " " & [Last Name] AS FullName, con.[Mobile Phone], con.[Home Phone], con.[E-mail Address] FROM -- 先关联通话表和“每个联系人的最新通话时间”子查询 (tblCalls c INNER JOIN (SELECT Contact, MAX([Call Time]) AS LatestCallTime FROM tblCalls GROUP BY Contact) AS LatestCalls ON c.Contact = LatestCalls.Contact AND c.[Call Time] = LatestCalls.LatestCallTime) -- 再关联联系人表,同时排除已归档的记录 INNER JOIN tblContacts con ON c.Contact = con.ID WHERE con.Archive = False;
方法2:用子查询直接取每个联系人的TOP1记录
如果同一个联系人可能在同一时间有多条通话,或者你需要按其他规则(比如通话ID倒序)取TOP1,用这种写法更灵活:
SELECT c.ID AS CallID, c.[Call Time], c.NextContact, c.Subject, c.Notes, [First Name] & " " & [Last Name] AS FullName, con.[Mobile Phone], con.[Home Phone], con.[E-mail Address] FROM tblContacts con -- LEFT JOIN可以保留没有通话记录的联系人,换成INNER JOIN则只显示有通话的联系人 LEFT JOIN (SELECT * FROM tblCalls c1 WHERE ID = (SELECT TOP 1 ID FROM tblCalls c2 WHERE c2.Contact = c1.Contact -- 这里可以修改排序规则,比如按Call Time DESC取最新,或者ID DESC取最新创建的 ORDER BY [Call Time] DESC)) AS c ON con.ID = c.Contact WHERE con.Archive = False;
关键说明
- 如果你需要的不是最新通话,只需要修改子查询里的
ORDER BY字段即可(比如换成NextContact ASC取最早的下次联系时间) - 用
LEFT JOIN会保留那些没有任何通话记录的联系人,如果不需要的话,把LEFT JOIN换成INNER JOIN就行 - 已归档的联系人通过
WHERE con.Archive = False直接排除,不会影响后续逻辑
内容的提问来源于stack exchange,提问作者BeardedSith
相关产品推荐
相关产品推荐

