1

私はいくつかのテーブルを持っています、books, bookcategories, categories

bookcategoriesとの間の多対多の関係を可能にする結合テーブルbooksですcategories

書籍にカテゴリが多い場合でも、書籍ごとに1行が返されるように、書籍のカテゴリ検索を実行できるようにしたいと考えています。

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ではない)本の行のみを返したいです

かなり基本的なものが欠けていると思わずにはいられません。誰か助けてもらえますか?

テーブルの構造を変更する必要がありますか、それとも必要なものを実現する方法がありますか。

4

3 に答える 3

1

これにより、カテゴリ1とカテゴリ2の両方を持つ書籍が返されます。

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

または、doubleexists句を使用することもできます。

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
        )
于 2012-07-01T16:44:43.307 に答える
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;
于 2012-07-01T17:48:25.327 に答える
-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

于 2012-07-01T16:52:40.070 に答える