复杂的MySQL join / where子句

时间:2013-02-02 20:58:30

标签: php mysql join

我的数据库中有2个表(实际上更多,但目前无关紧要)。

一个表存储状态为“发布”或“垃圾”的图书。根据该书是否随身携带,书籍具有发布或废弃状态。

另一个表存储有关特定用户是否阅读过特定图书的数据。

我想显示用户已阅读但尚未阅读的所有书籍的清单。我创建了一个查询,它将连接两个表并匹配每本书,无论状态如何,特定用户和读取日期,如果未读,则为NULL。问题是,虽然我想要显示用户尚未阅读的书籍,但我不想显示用户未阅读的书籍,这些书籍不再存在(具有垃圾状态)。

目前,我无法做到这一点。在我的PHP侧的foreach循环中,我正在检查是否已读取具有垃圾状态的书,如果没有,则跳过它。我觉得这在数据库方面是低效的。

以下是我目前的脚本。我想要完成的是什么?会不会有效率?谢谢你的帮助。

 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

假设$ userID是与用户相关的有效整数

2 个答案:

答案 0 :(得分:1)

而不仅仅是你的IN,你必须添加一些更复杂的子句。

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

答案 1 :(得分:0)

我认为您可以尝试先找到user_id并找到书籍。 这是一个例子:

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

通过这种方式,您应该只显示给定用户ID的post_status ='publish'或'trash'的书籍。