我有3张桌子:books
,book_categories
,categories
。
book_categories
表“加入”books
和categories
。它包含以下列:id
,book_id
,category_id
。
因此,一本书可能属于许多类别,而一个分类可能有很多书。
我需要查询从given_category
检索所有图书,但属于given_set_of_categories
的图书除外。因此,例如,我想要所有A类书籍,但前提是它们也不属于B类或C类。我还需要按Book.inserted列排序(排序)结果。
我知道如何从given_category
获取所有包含2个联接的书籍,但无法弄清楚如何从结果中排除其他类别的某些书籍。我无法用PHP过滤书籍,因为我正在对搜索结果进行分页。
答案 0 :(得分: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
答案 1 :(得分: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')
答案 2 :(得分:0)
我认为只要book_categories条目唯一,这可以通过计数来实现,因此组合book_id&amp; 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