在WHERE子句中使用来自连接表的COUNT

时间:2016-03-15 13:51:34

标签: mysql sql database

如果有一个表collections和一个表books,我需要一个查询来获取包含所有图书的单个集合,但前提是至少有一本图书是cover_image=1

使collectionsbooks之间的多对多关系变得复杂化。第三张表rel_collections_books将两者联系在一起。任何书籍都可以成为多个不同馆藏的一部分。

获取给定集合中所有书籍的查询是:

$id = 7; //the collection we want to fetch

SELECT b.*
FROM   books b
       LEFT JOIN rel_collections_books rel ON rel.book__id = b.id 
                                           AND rel.collection__id = '{$id}'
       LEFT JOIN collections c ON c.id = rel.collection__id
WHERE  c.id = '{$id}'

到目前为止这是有效的,但是当我运行下一个查询时,它仍会产生一个结果,它应该返回null:

//none of the books in the collection have cover_image=1, 
//so this query should produce nothing, but it does:

 SELECT b.*
    FROM   books b
           LEFT JOIN rel_collections_books rel ON rel.book__id = b.id 
                                               AND rel.collection__id = '{$id}'
           LEFT JOIN collections c ON c.id = rel.collection__id
    WHERE  c.id = '{$id}'
    AND EXISTS(
              SELECT NULL
              FROM   books b
                     LEFT JOIN rel_collections_books rel ON rel.book__id = b.id 
                                               AND rel.collection__id = '{$id}'
              WHERE  b.cover_image = '1'
              )

我该怎么做,和/或有更好的方法吗?谢谢。

1 个答案:

答案 0 :(得分:3)

您正在从特定集合中选择图书,因此LEFT JOIN在这里没有意义。此外,我不喜欢嵌套查询中的相同表别名,重命名它们会使事情更清晰。我认为应该工作:

 SELECT b.*
    FROM books b
        INNER JOIN rel_collections_books rel ON rel.book__id = b.id 
    WHERE rel.collection__id = '{$id}'
    AND EXISTS (
        SELECT 1
        FROM books b2
            INNER JOIN rel_collections_books rel2 ON rel2.book__id = b2.id 
        WHERE rel2.collection__id = c.id AND b2.cover_image = '1')