2012-11-16 26 views
1

我有3個表格:booksbook_categories,categories從一個類別中選擇除屬於其他類別的書籍以外的所有圖書

book_categories表「加入」bookscategories。它包含列:id,book_id,category_id

所以一本書可能屬於多個類別,一個類可能有很多書。

我需要查詢從given_category檢索所有書籍,但書籍屬於given_set_of_categories。例如,我想要所有來自類別A的書籍,但前提是它們不屬於類別B或C.我還需要通過Book.inserted列對結果進行排序(排序)。

我知道如何從given_category所有書籍中獲得2個連接,但無法弄清楚如何從其他類別中排除某些書籍。我無法過濾PHP中的書籍,因爲我正在對搜索結果進行分頁。

回答

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 
+0

作品不錯,但在given_set元素> 1它的工作原理很慢的 - 像15秒PN查詢......現在我要排除只有一個類別,它工作正常 – user606521

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') 
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 
相關問題