简体   繁体   中英

How do I efficiently select unique row/record data from 2 mysql tables and return one merged result, ordered by timestamp?

Stack:

I'm trying to turn my website's user profile into more of a feed style page. Currently the profile shows some user stats at the top, then the last 10 comments a user submitted (ordered by timestamp descending), then the last 10 posts they have submitted.

What I want to do instead, is have the last 20 "actions" (either comment or post submission) listed in order of the timestamp (so the comments and submissions will be merged together in the list instead of having 2 seperate lists). You know, like a "feed."

The issue is that the comments are pulled from a comments table, and the submissions are pulled from a "submissions" table.

I've solved it in a pretty inefficient way by using a union query to select "comment_id/submission_id", "field the identifies record as a comment or a submission", "timestamp" from both tables.

This gives me a result that tells my the entity id, as well as defines the entity as a comment or a post, by which I can then shoot off another query in a while mysql_fetch_array statement to get the full comment or submission data.

This just seems really dirty to me, since I'm basically querying the tables, finding the rows/records that I need (but ignoring the actual data I need since the different table's columns don't match up as I believe to be necessary for a union query), then going back for the data I ignored the first time with individual queries in a while statement...

Is there a better way to do this that I don't know of?

Additional notes:


Example sql I'm currently using to build the initial result I spoke of above:

select comment_id, datatype, timestamp from comments where userid=3
union all
select content_id, datatype, timestamp from submissions where userid=3
ORDER BY timestamp DESC

Returns a result like this:

commentid  datatype      timestamp 
5201       post          2012-03-27 20:30:40
43761      comment       2012-03-26 21:00:19
43759      comment       2012-03-26 20:59:47
5033       post          2012-03-26 20:57:36
43755      comment       2012-03-26 20:54:57
43745      comment       2012-03-26 16:32:24

Pseudocode I can then use to print out the information onto the profile page:

while ($content_array = mysql_fetch_array($abovequery)){

Individual select query fetching the full row by from either comment table or submission table by id depending on $content_array['datatype'];

echo out relevant data from individual select query onto profile screen in a pretty way;

}

Surely this can be done better?

If you are unable to coerce the columns of the two full queries in such a way that it can all be returned in the UNION then you could join the union result to the comments and submissions tables.

SELECT records.datatype, comments.*, submissions.*
FROM (
    (
        SELECT comment_id, datatype
        FROM comments
        WHERE userid=3
        ORDER BY timestamp DESC
        LIMIT 20
    ) UNION ALL (
        SELECT content_id, datatype
        FROM submissions
        WHERE userid=3
        ORDER BY timestamp DESC
        LIMIT 20
    )
    ORDER BY timestamp DESC
    LIMIT 20
) AS records
LEFT JOIN comments
    ON records.comment_id = comments.comment_id
    AND records.datatype = 'comment'
LEFT JOIN submissions
    ON records.comment_id = submissions.content_id
    AND records.datatype = 'post'

Alternatively, you could run the two innermost selects with all required fields and then order the final result in PHP.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM