尝试:
select book_id
from categories
group by book_id
having sum((cat_id in (1,3))::int) = 2
或者,如果你打算从支持直接传递数组给它(这样的:http://fxjr.blogspot.com/2009/05/npgsql-tips-using-in-queries-with.html)语言传递一个数组Postgres的,使用这样的:
select book_id
from categories
group by book_id
having sum((cat_id = ANY(ARRAY[1,3]))::int) = 2
如果你想得到书名:
select categories.book_id, books.name
from categories
join books on books.id = categories.book_id
group by categories.book_id
,books.name
having sum((categories.cat_id in (1,3))::int) = 2
@Evan Carroll,修改查询:
ANSI SQL的方式:
select categories.book_id, books.name
from categories
join books on books.id = categories.book_id
group by categories.book_id
,books.name
having count(case when categories.cat_id in (1,3) then 1 end) = 2
三世书名称:
select book_id
from categories
group by book_id
having count(case when cat_id in (1,3) then 1 end) = 2
什么是内联的条件和相同的条款中(即其计数值的优势。having
),而不是单独把条件where
条款及其having
条款计数?...
select book_id
from categories
where category_id in (1,3)
group by book_id
having count(*) = 2
...如果我们两个内嵌的条件和条款having
其计数值,我们可以很方便的我们可以通过查询所有分类为1和3的书籍,或者分类为2和3和4的。面向未来的FTW!此外,对组合类别和数量的测试彼此相邻,再加上可读性因素。
为了方便那种查询:
select book_id
from categories
group by book_id
having
count(case when cat_id in (1,3) then 1 end) = 2
or count(case when cat_id in (2,3,4) then 1 end) = 3
要达到的性能(有时,实现了性能和可读性;不要拌匀),必须复制having子句,其中的元素测试条款:
select book_id
from categories
where cat_id in (1,2,3,4)
group by book_id
having
count(case when cat_id in (1,3) then 1 end) = 2
or count(case when cat_id in (2,3,4) then 1 end) = 3
[编辑]
顺便说一句,这里的惯用MySQL的:
select book_id
from categories
group by book_id
having sum(cat_id in (1,3)) = 2
这看起来相当尴尬,而且是错误的。sum用于添加参数,'count()'用于对行进行计数。看到我的答案更容易做到这一点。 – 2010-06-23 14:52:58
之前你说这是错的,这是一个习惯性的postgres。如果我使用mysql,我会这样做:'sum(categories.cat_id in(1,3))',因为在mysql中,布尔和整数是相同的,它们在幕后只有1和0 ,所以不需要更多的铸造。对于postgresql,我们只需要将布尔值转换为整数就可以按照预期工作。好的,为你我会使它符合ANSI SQL。编辑即将到来 – 2010-06-23 15:04:23