2

我有两个表,Clients并且Contacts(见下文),并且想要获取所有客户,只有他们最后添加的联系人。

我几乎正在考虑使用子查询,因为我无法LIMIT 1在我加入的联系人上使用,直到我偶然发现了这个似乎很简单的解决方案。

问题是,我真的不明白它在做什么。该WHERE条款背后的逻辑也超出了我的理解。

对此的附带问题:两个连接仍然比子查询快吗?

PS:我正在使用MySQL。

谢谢。

SELECT
    cl.clientId as clientId,
    cl.clientName as clientName,
    c1.firstName as firstName,
    c1.lastName as lastName,
    c1.added as added
FROM Clients as cl
LEFT JOIN Contacts as c1 ON cl.clientId = c1.clientId
LEFT JOIN Contacts as c2 ON cl.clientId = c2.clientId AND c1.added < c2.added
WHERE c2.added IS NULL

客户

-----------------------------
 clientId     clientName
-----------------------------
    1          Johnny's
    2          Bonnie's

联系人

-------------------------------------------------------
 clientId     firstName     lastName        added
-------------------------------------------------------
    1          Johnny        Simmons      2013-06-17
    1          Jane          Simmons      2013-06-18
    2          Bonnie        Hall         2013-06-19

结果

----------------------------------------------------------------------
 clientId     clientName     firstName     lastName        added
----------------------------------------------------------------------
    1          Johnny's       Jane          Simmons      2013-06-18
    2          Bonnie's       Bonnie        Hall         2013-06-19
4

2 回答 2

4
LEFT JOIN Contacts as c2 ON cl.clientId = c2.clientId AND c1.added < c2.added
WHERE c2.added IS NULL

该子句说: matchwhere中不能有一行。这会过滤掉之前添加的其他联系人存在的所有联系人。Contactscl.clientId = c2.clientId AND c1.added < c2.added

因此,您最终会获得每位客户的最新联系人。

于 2013-06-19T19:21:21.743 回答
1

THELEFT JOIN ... WHERE NULL等价于这个NOT EXISTS()查询。平台之间的性能可能不同(人们期望两个版本的查询计划相同) Mysql 人似乎更喜欢max(added)子查询。

SELECT
    cl.clientId as clientId,
    cl.clientName as clientName,
    c1.firstName as firstName,
    c1.lastName as lastName,
    c1.added as added
FROM Clients as cl
LEFT JOIN Contacts as c1 ON cl.clientId = c1.clientId
WHERE NOT EXISTS (
  SELECT 1 FROM Contacts as c2 
  WHERE cl.clientId = c2.clientId
    AND c1.added < c2.added
  );

解释与@Andomar 的答案相同,如果 c1. added 是最大值(对于此 client_id),则不能存在另一条具有更高值的记录(对于此 client_id)

于 2013-06-19T19:31:32.980 回答