简体   繁体   中英

How to fix sql statement with joins?

In my MySQL query, I try to get threads and for each thread, the most recent comment, and some image from another table. This works but has one problem. If the thread has no comments, then it won't be included. I want it so that, if the thread has no comments, then it should still be included, but the comment columns should have null, and image_id should be null too.

Does anyone know how I can do this?

Thanks

SELECT t.id,t.user_id,t.title,c.comment,d.has_answer,d.recent_date,MIN(i.id) image_id 
FROM threads t 
INNER JOIN comments c ON c.thread_id = t.id
INNER JOIN (
    SELECT  thread_id, MAX(date_sent) recent_date, MAX(is_answer) has_answer
    FROM    comments
    GROUP   BY thread_id
) d ON d.thread_id = c.thread_id AND d.recent_date = c.date_sent
LEFT JOIN thread_images i ON t.id = i.thread_id
GROUP BY t.id

UPDATE

This one sorta works, but it makes the recent_date somehow have a date, when there is no comments. It should be null in that case...

SELECT t.id,t.user_id,t.title,c.comment,d.has_answer,d.recent_date
FROM threads t 
left JOIN comments c ON c.thread_id = t.id
inner JOIN (
    SELECT  thread_id, MAX(date_sent) recent_date, MAX(is_answer) has_answer
    FROM    comments
    GROUP   BY thread_id
) d ON c.thread_id IS NULL OR (d.thread_id = c.thread_id AND d.recent_date = c.date_sent)
GROUP BY t.id

UPDATE 2

This one seems to work ok, but seems weird

SELECT t.id,t.user_id,t.title,c.comment,d.has_answer, IF(c.id IS NULL, NULL, d.recent_date) recent_date,MIN(i.id) image_id 
FROM threads t 
LEFT JOIN comments c ON c.thread_id = t.id
INNER JOIN (
    SELECT  thread_id, MAX(date_sent) recent_date, MAX(is_answer) has_answer
    FROM    comments
    GROUP   BY thread_id
) d ON c.id IS NULL OR (d.thread_id = c.thread_id AND d.recent_date = c.date_sent)
LEFT JOIN thread_images i ON t.id = i.thread_id

GROUP BY t.id

Here it is via left-joins.

SELECT 
      t.id,
      t.user_id,
      t.title,
      c.comment,
      d.has_answer,
      d.recent_date,
      MIN(i.id) image_id 
   FROM 
      threads t
         LEFT JOIN comments c 
            ON t.id = c.thread_id
            LEFT JOIN ( SELECT
                               thread_id, 
                               MAX(date_sent) recent_date, 
                               MAX(is_answer) has_answer
                            FROM
                               comments
                            GROUP BY 
                               thread_id ) d 
               ON c.thread_id = d.thread_id
              AND c.date_sent = d.recent_date
         LEFT JOIN thread_images i 
            ON t.id = i.thread_id
   GROUP BY 
      t.id

However, being a web-based system, I would strongly consider adding a couple records to the main thread for most recent comment, minimum image ID, id for the answer so you don't have to do aggregates for MIN( image ), max (isAnswer), max( comment date ) to get values. Instead, use triggers. When a comment is added to a thread, just update the thread with that ID. For an image, if you want the minimum ID, then if no previous image, and a new on added, update the thread with the first image saved. Similarly with an answer being established. So, the triggers are done at the moment of saving and you don't have to deal with more complex querying, you can just left-join on the table.column as available.

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