MYSQL Query - Get latest comment related to the post

前端 未结 6 996
刺人心
刺人心 2021-01-11 20:38

I am trying to get the latest 1 or 2 comments related to each post I download, a bit like instagram does as they show the latest 3 comments for each post, So far I am gettin

6条回答
  •  抹茶落季
    2021-01-11 21:31

    UNTESTED: I would recommend putting together an SQL fiddle with some sample data and your existing table structure showing the problem; that way we could play around with the responses and ensure functionality with your schema.

    So we use a variables to simulate a window function (Such as row_number)

    in this case @Row_num and @prev_Value. @Row_number keeps track of the current row for each post (since a single post could have lots of comments) then when the a new post ID (UUIDPOST?) is encountered the row_num variable is reset to 1. When the current records UUIDPOST matches the variable @prev_Value, we simply increment the row by 1.

    This technique allows us to assign a row number based on the date or activity ID order descending. As each cross join only results in 1 record we don't cause duplicate records to appear. However, since we then limit by row_number < = 2 we only get the two most recent comments in our newly added left join.

    This assumes posts relation to users is a Many to one, meaning a post can only have 1 user.

    Something like This: though I'm not sure about the final left join I need to better understand the structure of the activity table thus a comment against the original question.

    SELECT Posts.id,
            Posts.uuid,
            Posts.caption,
            Posts.path,
            Posts.date,
            USERS.id,
            USERS.username,
            USERS.fullname,
            USERS.profileImage,
            coalesce(A.LikeCNT,0)
            com.comment
        FROM Posts 
        INNER JOIN USERS 
          ON Posts.id = 145 
         AND USERS.id = 145
        LEFT JOIN (SELECT COUNT(A.uuidPost) LikeCNT, A.UUIDPost
            FROM Activity A
            WHERE type =  'like' 
            GROUP BY A.UUIDPOST) A
         on A.UUIDPost=Posts.uuid
    
    
      --This join simulates row_Number() over (partition by PostID, order by activityID desc)  (Nice article [here](http://preilly.me/2011/11/11/mysql-row_number/) several other examples exist on SO already.
       --Meaning.... Generate a row number for each activity from 1-X restarting at 1 for each new post but start numbering at the newest activityID)
    
        LEFT JOIN (SELECT comment, UUIDPOST, @row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number,@prev_value := UUIDPOST
    
                   FROM ACTIVITY 
                   CROSS JOIN (SELECT @row_num := 1) x
                   CROSS JOIN (SELECT @prev_value := '') y
                   WHERE type = 'comment'
                   ORDER BY UUIDPOST, --Some date or ID desc) Com
           on Com.UUIIDPOSt = Posts.UUID
           and row_number < = 2
    
    
      -- Now since we have a row_number restarting at 1 for each new post, simply return only the 1st two rows.
    
        ORDER BY date DESC
        LIMIT 0, 5
    

    we had to put the and row_number < = 2 on the join itself. If it was put in the where clause you would lose those posts without any comments which I think you still want.

    Additionally we should probably look at the "comment" field to make sure it's not blank or null, but lets make sure this works first.

提交回复
热议问题