2012-07-01 18 views
1

我有幾個表返回單列,books, bookcategories, categories連接表,其中> 1行中的子表

bookcategories是連接表,讓許多人bookscategories之間一對多的關係。

我希望能夠在書上運行類別搜索,以便即使書中有很多類別時,搜索也會返回每行一行。

書籍

ID | Title 
1 | Once upon... 
2 | How many... 
3 | How much... 

分類

ID | Category 
1 | x 
2 | y 
3 | z 

BookCategories

BookId | CategoryId 
    1 |  1 
    1 |  2 
    2 |  2 
    2 |  3 
    2 |  1 
    3 |  1 

我以爲我可以逃脫這個:

SELECT b.Id, 
    b.Title, 
FROM (books b 
    INNER JOIN bookcategories bc ON b.ID= bc.BookId 
    ) 
WHERE (bc.categoryId =1 AND bc.categoryId=2) 
GROUP BY b.Id, b.Title 

但是,只要我添加AND,查詢就不會返回任何行。但是,這是我需要申請的標準 - 我只想返回書籍行,其中書籍同時具有上述類別1和2(即,不是類別1或類別2)

不禁讓我以爲我失蹤一些基本的東西。誰能幫忙?

我需要改變表格的結構還是有辦法實現我所需要的。

+1

我認爲你需要重新字你的問題。代碼示例之前的文本告訴與您的代碼示例之後的代碼稍有不同的故事(由兩個給出不同結果的答案所證明)。與其試圖用文字解釋這一點,你能告訴我們究竟應該從樣本數據中返回哪些行嗎? –

回答

1

這應該歸還圖書有兩個類別之一,之二:

select b.Id 
,  b.Title 
from books b 
join bookcategories bc 
on  bc.BookId = b.Id 
group by 
     b.Id 
,  b.Title 
having sum(case when bc.categoryId = 1 then 1 end) > 0 
     and sum(case when bc.categoryId = 2 then 1 end) > 0 

另外,也可以使用雙exists條款:

select b.Id 
,  b.Title 
from books b 
where exists 
     (
     select * 
     from bookcategories bc 
     where bc.BookId = b.Id 
       and bc.CategoryId = 1 
     ) 
     and exists 
     (
     select * 
     from bookcategories bc 
     where bc.BookId = b.Id 
       and bc.CategoryId = 2 
     ) 
+0

有趣的是 - 這兩個工作 - 謝謝 – wingyip

+0

謝謝Andomar - 現在已經實施上面的第二個例子。 – wingyip

-1

嘗試增加select distinct和改變and改爲or

SELECT  DISTINCT b.Id, b.Title 
FROM  books b 
INNER JOIN bookcategories bc ON b.ID= bc.BookId 
WHERE  (bc.categoryId=1 OR bc.categoryId=2) 
ORDER BY b.ID 

distinct關鍵字不會返回重複的行;所以你現在可以使用categoryID = 1 OR categoryID = 2

+0

這不做我需要它做不幸的事情。以上內容並不排除不具備這兩種類別的書籍。 – wingyip

0

另一種選擇(至少根據我想你想要):

SELECT ID, Title 
FROM 
(
    SELECT b.ID, b.Title, c = COUNT(bc.BookID) 
    FROM dbo.Books AS b 
    INNER JOIN dbo.BookCategories AS bc 
    ON b.ID = bc.BOokID 
    AND bc.CategoryID IN (1,2) 
    GROUP BY b.ID, b.Title 
) AS x 
WHERE c >= 2; -- in case there is no unique constraint on BookCategories 

雖然這應該也行:

SELECT b.ID, b.Title 
    FROM dbo.Books AS b 
    INNER JOIN dbo.BookCategories AS bc 
    ON b.ID = bc.BOokID 
    AND bc.CategoryID IN (1,2) 
GROUP BY b.ID, b.Title 
HAVING COUNT(*) >= 2; 
+0

感謝這兩者都工作,儘管已經實施使用Andomar的存在示例。無論如何,非常感謝 - 真正有幫助的人已經學到了很多關於子查詢的知識。 w ^ – wingyip

相關問題