我有几张表books, bookcategories, categories
bookcategories
是一个联接表,允许books
和categories
之间的多对多关系。
我希望能够在书籍上运行类别搜索,这样即使书籍有很多类别,搜索也会为每本书返回一行。
图书
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)
不禁想到我遗漏了一些非常基本的东西。有人可以帮忙吗?
我是否需要更改表格的结构,或者是否有办法实现我的需要。
永
答案 0 :(得分: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
)
答案 1 :(得分: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;
答案 2 :(得分:-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
。