1

我有 3 张桌子:books, book_categories, categories.

book_categories表“连接”bookscategories. 它包含列:idbook_idcategory_id

所以一本书可能属于许多类别,而一个类别可能有很多书。

given_category我需要查询,它从属于的书籍除外的所有书籍中检索所有书籍given_set_of_categories。因此,例如,我想要 A 类的所有书籍,但前提是它们不属于 B 类或 C 类。我还需要按 Book.inserted 列对结果进行排序(排序)。

我知道如何从given_category2 个连接中获取所有书籍,但不知道如何从结果中排除其他类别的一些书籍。我无法在 PHP 中过滤书籍,因为我正在对搜索结果进行分页。

4

3 回答 3

1
where
  category_id = <given category>
  and books.book_id not in
(
 select book_id from book_categories
  where category_id in (<given set of cat>)
)
order by books.inserted
于 2012-11-16T00:24:18.470 回答
0

我认为这可以通过计数来实现,前提是 book_categories 条目是唯一的,因此book_id 和 category_id 的组合重复。我们不是直接尝试排除记录,而是从组合的类别集中进行选择 [,] 然后我们将计算 book_id 属于的条目:

COUNT(IF(category_id = <given_category>, 1, NULL)) as cnt_exists

在确保它包含所需的类别之后,我们计算总数以查看它是否也属于任何其他类别:

COUNT(*) AS cnt_total


SELECT * FROM books b JOIN (
  SELECT book_id, 
         COUNT(IF(category_id = <given_category>, 1, NULL)) as cnt_exists, 
         COUNT(*) AS cnt_total FROM book_categories WHERE
         category_id IN(<given_category>, <given_set_of_categories>)
) bc ON b.id = bc.book_id AND 
        cnt_exists = 1 AND cnt_total = 1 ORDER BY b.inserted
于 2012-11-17T07:48:11.807 回答
0

因此,如果您的意思是它属于一个类别而不属于任何其他类别:

AND EXISTS(SELECT * FROM books b JOIN book_categories bc ON b.id = bc.book_id JOIN categories c ON bc.category_id = c.id AND c.id = 'A')
AND NOT EXISTS(SELECT * FROM books b JOIN book_categories bc ON b.id = bc.book_id JOIN categories c ON bc.category_id = c.id AND c.id != 'A')
于 2012-11-16T00:26:24.087 回答