Here are the three queries that you'll be needing (for a default install of Vanilla):
Fetch Threads
I exclude threads which are private message conversations by checking that the discussion itself isn't a whisper to someone else.
Code:
SELECT *
FROM {$tableprefix}Discussion
WHERE WhisperUserId = 0
ORDER BY UserID LIMIT {$start_at}, {$per_page}
Fetch Posts
I exclude all posts that belong to a discussion that is being whispered to someone, and all posts within a thread that is a whisper.
Code:
SELECT C.*
FROM {$tableprefix}Comment C
,{$tableprefix}Discussion D
WHERE D.DiscussionID = C.DiscussionID
AND D.WhisperUserID = 0
AND C.WhisperUserID = 0
ORDER BY CommentID
LIMIT {$start_at}, {$per_page}
Fetch Private Messages
Three parts to this:
1) Fetch all inline whispers and give them a subject based on the first 80 characters of the body.
2) Fetch all of the discussion whispers where the author of the discussion is talking
3) Fetch all of the discussion whispers where a person is responding to the author
Code:
SELECT LEFT(C.Body,80) Subject
,C.CommentID
,C.DiscussionID
,C.AuthUserID
,C.DateCreated
,C.EditUserID
,C.DateEdited
,C.WhisperUserID
,C.Body
,C.FormatType
,C.Deleted
,C.DateDeleted
,C.DeleteUserID
,C.RemoteIp
FROM {$tableprefix}Comment C
,{$tableprefix}Discussion D
WHERE D.DiscussionID = C.DiscussionID
AND C.WhisperUserID != 0
UNION ALL
SELECT D.Name Subject
,C.CommentID
,C.DiscussionID
,C.AuthUserID
,C.DateCreated
,C.EditUserID
,C.DateEdited
,D.WhisperUserID
,C.Body
,C.FormatType
,C.Deleted
,C.DateDeleted
,C.DeleteUserID
,C.RemoteIp
FROM {$tableprefix}Comment C
,{$tableprefix}Discussion D
WHERE D.DiscussionID = C.DiscussionID
AND D.WhisperUserID != 0
AND C.AuthUserID = D.AuthUserID
UNION ALL
SELECT D.Name Subject
,C.CommentID
,C.DiscussionID
,D.WhisperUserID AuthUserID
,C.DateCreated
,C.EditUserID
,C.DateEdited
,D.AuthUserId WhisperUserID
,C.Body
,C.FormatType
,C.Deleted
,C.DateDeleted
,C.DeleteUserID
,C.RemoteIp
FROM {$tableprefix}Comment C
,{$tableprefix}Discussion D
WHERE D.DiscussionID = C.DiscussionID
AND D.WhisperUserID != 0
AND C.AuthUserID != D.AuthUserID
ORDER BY CommentID
LIMIT {$start_at}, {$per_page}
Using those to source the data load would solve it all.