To jest greatest-n-per-group problem, który jest często zadawane w Stack Overflow.
Oto jak rozwiązałbym to w twoim scenariuszu:
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;
Oznacza to, że chcemy mh być najnowszym wierszem w tbl_member_login_history dla danego elementu członkowskiego. Więc szukamy kolejnego wiersza mh2 to jest jeszcze nowsze. Jeśli nie jest nowszy niż mh zostanie znaleziony wiersz, a następnie mh2.* będzie NULL, więc mh musi być najnowszy.
Zakładam, że ta tabela ma kolumnę klucza podstawowego, która zawiera rosnące wartości. W tym przykładzie zakładam, że nazwa kolumny to pk .
Używanie LEFT OUTER JOIN dla obu odniesienia do tabeli historii logowania oznaczają, że m wiersz zostanie zgłoszony, nawet jeśli nie ma pasującego wiersza.