Sql server 从联接表返回单行,其中>;子表中的1行

Sql server 从联接表返回单行,其中>;子表中的1行,sql-server,tsql,Sql Server,Tsql,我有几个表格,书籍,书籍类别,类别 bookcategories是一个联接表,允许books和categories之间的多对多关系 我希望能够在书籍上运行类别搜索,这样即使书籍有许多类别,搜索也会返回每本书一行 书籍 ID | Title 1 | Once upon... 2 | How many... 3 | How much... ID | Category 1 | x 2 | y 3 | z BookId | CategoryId

我有几个表格,
书籍,书籍类别,类别

bookcategories
是一个联接表,允许
books
categories
之间的多对多关系

我希望能够在书籍上运行类别搜索,这样即使书籍有许多类别,搜索也会返回每本书一行

书籍

ID   | Title
1    | Once upon...
2    | How many...
3    | How much...
ID   | Category
1    | x
2    | y
3    | z
   BookId | CategoryId
     1    |     1
     1    |     2
     2    |     2
     2    |     3
     2    |     1
     3    |     1
类别

ID   | Title
1    | Once upon...
2    | How many...
3    | How much...
ID   | Category
1    | x
2    | y
3    | z
   BookId | CategoryId
     1    |     1
     1    |     2
     2    |     2
     2    |     3
     2    |     1
     3    |     1
图书类别

ID   | Title
1    | Once upon...
2    | How many...
3    | How much...
ID   | Category
1    | x
2    | y
3    | z
   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)

我禁不住想我错过了一些基本的东西。有人能帮忙吗

我是否需要改变表格的结构,或者是否有办法实现我所需要的


Wing

这应该返回同时包含第一类和第二类的书籍:

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
或者,您可以使用double
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
        )

尝试添加
选择distinct
,并将
更改为

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
关键字不会返回重复的行;因此,您现在可以使用另一种选择(至少基于我认为您想要的):

尽管这也应该起作用:

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;

我想你需要重新回答你的问题。代码示例之前的文本讲述的故事与代码示例之后的代码讲述的故事稍有不同(这可以从给出不同结果的两个答案中得到证明)。与其试图用文字来解释这一点,不如告诉我们应该从示例数据中返回哪些行好吗?不幸的是,这并不能满足我的需要。以上内容并不排除没有这两个类别的书籍。感谢它们,尽管它们已经使用Andromar的exists示例实现了,但这两个类别都可以工作。无论如何,非常感谢-非常有帮助,我已经了解了很多关于子查询的知识。WThanks Andomar-现在已经使用上面的第二个示例实现了。