Php 复杂MySQL join/where子句

Php 复杂MySQL join/where子句,php,mysql,join,Php,Mysql,Join,我的数据库中有两个表(实际上更多,但目前不关心它们) 一个表存储状态为“发布”或“垃圾”的书籍。图书的状态为“发布”或“垃圾”,具体取决于该图书是否已被携带 另一个表存储特定用户是否阅读过特定书籍的数据 我想显示一个列表,列出用户已经读过和还没有读过的书,这些书仍然随身携带。我创建了一个查询,该查询将连接两个表,并将每本书和特定用户以及读取日期(若未读取,则为NULL)进行匹配,而不管其状态如何。问题是,虽然我希望显示用户尚未阅读的书籍,但我不希望显示用户尚未阅读但不再携带的书籍(状态为“垃圾箱

我的数据库中有两个表(实际上更多,但目前不关心它们)

一个表存储状态为“发布”或“垃圾”的书籍。图书的状态为“发布”或“垃圾”,具体取决于该图书是否已被携带

另一个表存储特定用户是否阅读过特定书籍的数据

我想显示一个列表,列出用户已经读过和还没有读过的书,这些书仍然随身携带。我创建了一个查询,该查询将连接两个表,并将每本书和特定用户以及读取日期(若未读取,则为NULL)进行匹配,而不管其状态如何。问题是,虽然我希望显示用户尚未阅读的书籍,但我不希望显示用户尚未阅读但不再携带的书籍(状态为“垃圾箱”)

目前,我无法做到这一点。在PHP端的foreach循环中,我检查一本状态为trash的书是否已被阅读,如果没有,则跳过它。我觉得这在数据库方面效率很低

下面是我目前拥有的脚本。我想实现的目标可能实现吗?效率是高还是低?谢谢你的帮助

 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是一个与用户相关的有效整数,而不仅仅是您的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
选择
book.ID作为实际的\u book\u ID,
书名,
book.post_状态,
阅读*
从书变成书
左外连接book_club,如图所示
ON read.book_id=book.id
和read.user_id=$userID
其中book.post_type='book'
和(book.post_status='publish'或
(book.post_status='trash'和read.IS不为空)
订购人
书名

我认为您可以尝试在用户id之前查找书籍,在用户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'的书籍。

这很有效。谢谢MySQL从外部联接中删除“LEFT”时会抛出错误,这有什么原因吗?仅使用外部联接是不起作用的??它不会起作用,但左联接就足够了(您可能有一个右外部联接,所以我认为仅使用外部联接还不够清楚):请参见Ok。问题是,虽然上面的脚本完全满足了我的需要,但执行大约需要18秒。读取表中有40K行。这听起来正常吗?或者你认为服务器升级会起作用吗(目前在共享服务器上)?@Chris说实话,我建议你就具体的性能问题再问一个问题,我必须承认我不是专家……谢谢。问题是缺少索引。现在跑得又快又平稳。再次感谢!