MySQL子查询 - 只查找LEFT JOIN中的第一条记录

时间:2012-01-23 19:57:26

标签: mysql subquery greatest-n-per-group

我正在尝试显示成员记录列表,我有一些表格用于显示我需要的内容。

这很容易。我需要帮助的部分是一个表,每个成员记录有许多记录:登录历史

我想只显示登录历史记录表中存在的每个成员记录的第一行。或者,我可能想要翻转并在登录历史记录表中显示最后一条记录。

这是我到目前为止所得到的:

SELECT m.memberid, m.membername, m.gender, mp.phone
FROM tbl_members m, 
     tbl_members_phones mp, 
     tbl_members_addresses ma
WHERE m.defaultphoneid = mp.phoneid
AND m.defaultaddressid = ma.addressid

这样可以返回预期的内容。

tbl_members_login_history中我要添加到返回结果的2列:mh。loggedtime,mh。ipaddy

我知道添加tbl_members_login_history作为LEFT JOIN会返回重复项,所以我认为这里必须有子查询必需,才能返回存在的memberid的第一条记录在tbl_members_login_history

我担心的是,如果历史记录表中没有记录,我仍然希望显示该成员信息,但将历史记录列保留为NULL。

这会是子查询事件吗?如果是这样,如何添加那种LIMIT?

2 个答案:

答案 0 :(得分:20)

这是greatest-n-per-group问题,在Stack Overflow上经常被问到。

以下是我在你的场景中如何解决它:

SELECT m.memberid, m.membername, m.gender, mp.phone, mh.loggedtime, mh.ipaddy
FROM tbl_members m 
INNER JOIN tbl_members_phones mp ON m.defaultphoneid = mp.phoneid
INNER JOIN tbl_members_addresses ma ON m.defaultaddressid = ma.addressid
LEFT OUTER JOIN tbl_members_login_history mh ON m.memberid = mh.memberid
LEFT OUTER JOIN tbl_members_login_history mh2 ON m.memberid = mh2.memberid
    AND mh.pk < mh2.pk
WHERE mh2.pk IS NULL;

也就是说,我们希望mh成为给定memberid的tbl_member_login_history中的最新行。因此,我们搜索更新的另一行mh2。如果找不到mh行的最新内容,则mh2.*将为NULL,因此mh必须是最新的。

我假设这个表有一个包含增加值的主键列。对于此示例,我假设列名称为pk

两个使用LEFT OUTER JOIN对登录历史记录表的引用意味着即使没有匹配的行,也会报告m行。

答案 1 :(得分:0)

像这样添加

LEFT OUTER JOIN (SELECT member_id, MAX(LAST_LOGIN_DATE) from tbl_members_login_history) Last_Login ON Last_Login.memberid = m.memberid

PS。 LAST_LOGIN_DATE是伪列,您可以尝试使用restictive列