简体   繁体   中英

Complex MySQL join/where clause

I have 2 tables in my database (actually more, but they are of no concern currently).

One table stores books with a status of 'publish' or 'trash'. Books have a status of publish or trash based on whether that book is carried any longer.

The other table stores data on whether a particular user has read a specific book or not.

I would like to display a list of all books that the user has read and have yet to read which are still carried. I have created a query which will join both tables and match up each book, regardless of status, with the a specific user and the date read or NULL if unread. The problem is, while I would like to display books the user has not yet read, I do not want to display books the user has not read that are not carried any longer (have a status of trash).

Currently, I have been unable to accomplish that. In my foreach loop on the PHP side, I am checking to see if a book with a status of trash has been read and if not, skipping over it. This is inefficient on the database side I feel.

Below is the script I currently have. Is what I am trying to accomplish even possible? Would it be more or less efficient? Thanks for the help.

 SELECT 
     book.ID as actual_book_id,
     book.post_title,
     book.post_status,
     read.*
 FROM books as book
 LEFT OUTER JOIN book_club as read
     ON read.book_id = book.ID
     AND read.user_id = $userID
 WHERE book.post_type = 'book'
     AND book.post_status IN ('publish','trash')
 ORDER BY
     book.post_title ASC

Assume $userID is a valid integer relating to a user

instead of just your IN, you must add a little bit more complex clause.

SELECT 
     book.ID as actual_book_id,
     book.post_title,
     book.post_status,
     read.*
 FROM books as book
 LEFT OUTER JOIN book_club as read
     ON read.book_id = book.ID
     AND read.user_id = $userID
 WHERE book.post_type = 'book'
     AND (book.post_status  = 'publish' OR
          (book.post_status = 'trash' AND read.<columnDate> IS NOT NULL))
 ORDER BY
     book.post_title ASC

I think you can try to find before for the user_id and after find the books. Here's the example:

SELECT 
     book.id as actual_book_id,
     book.post_title,
     book.post_status,
     r.*
FROM 
(
      SELECT 
           user_read.* 
      FROM book_club AS user_read 
      WHERE user_read.user_id = $userID
) AS r 
LEFT JOIN books as book ON r.book_id = book.id 
WHERE book.post_type = 'book'
     AND book.post_status IN ('publish','trash')
 ORDER BY
     book.post_title ASC

By this way you should show ONLY the books with the post_status = 'publish' or 'trash' for the given userID.

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