2013-08-02 54 views
0

我遇到了我的小型电影数据库标记/类别查询问题。选择多个电影类别

我的表是:

ID(index),Name(film name),category 

一个电影可以有多个类别。

SELECT Name FROM categorytable WHERE category ='Action'; 

工作正常,但如果我想其他的标签,我得到空光标:

SELECT Name FROM categorytable WHERE category ='Action' AND category ='Sci-Fi'; 

实例选择:

1 Film001  Action 
2 Film001  Sci-Fi 
3 Film002  Action 

编辑: 我家databese:

ID|NAMEFILM|DESCRIPTION 

并且完整查询:

SELECT DATABASEFILM.NAMEFILM , DATABASEFILM.DESCRIPTION , NAME from DATABASEFILM , CATEGORY where DATABASEFILM.NAMEFILM=NAME AND category=(SELECT NAME FROM CATEGORY WHERE category ='Action'); 
+1

你试过'OR'吗? 'SELECT Name FROM categorytable WHERE category ='Action'OR category ='Sci-Fi''; – Jack

+1

'在哪里类别IN('Action','科幻');' –

+0

当我使用OR查询作品,但找到所有'动作'电影,但不一定'科幻'。 – Shu

回答

3

您的查询不起作用的原因是因为每一行只有一个类别。相反,你需要做聚合。我更喜欢做having条款中的条件,因为这是一种常规方法。

SELECT Name 
FROM categorytable 
group by Name 
having sum(case when category ='Action' then 1 else 0 end) > 0 and 
     sum(case when category ='Sci-Fi' then 1 else 0 end) > 0; 

having中的每个子句都在测试是否存在一个类别。如果,例如,您更改的问题是“动作片是科幻”,那么你就通过使第二个条件相等的改变having子句0:

having sum(case when category ='Action' then 1 else 0 end) > 0 and 
     sum(case when category ='Sci-Fi' then 1 else 0 end) = 0; 
+1

这是不对的。如果按类别分组,则每个分类最后一行。分组结果中的任何一行都不能匹配两个不同的类别,因为有助于结果行的行都具有相同的类别。我想你打算按姓名分组。 –

+0

@SteveKass。 。 。接得好。按照你的建议,这应该是“按名称分组”。 –

1

可以使用或条款,或者如果你有多个类别,它可能会更容易在

因此,无论

SELECT Name FROM categorytable WHERE category ='Action' OR category ='Sci-Fi' 

或者使用IN

使用
SELECT Name 
FROM categorytable 
WHERE category IN ('Action', 'Sci-Fi', 'SomeOtherCategory ') 

使用IN应该编译为相同的东西,但如果你明星更容易阅读不只是增加两个类别。

+0

但是,如果我想要“行动”和“科幻”的示例电影不仅“行动”? – Shu

0
with mustAppear(category) as (
    select 'Action' 
    union all 
    select 'Sci-Fi' 
) 
    select Name -- select those film names for which 
    from categorytable as C1 
    where not exists (-- there is no category that must appear with that name 
    select M.category 
    from mustAppear as M 
    where not exists (-- that does not. 
     select * 
     from categorytable as C2 
     where C2.Name = C1.Name 
     and C2.category = M.category 
    ) 
) 

您还可以更直接的是这样的:

select Name 
from categorytable 
where category = 'Sci-Fi' 
intersect 
select Name 
from categorytable 
where category = 'Action'; 

前查询的好处是,你可以使用它没有修改,如果你创建一个永久表(mustAppear,或者您可以使用一个表变量@mustAppear)至持有类别必须匹配的ry列表。后者的查询比较简单,但在类别更改时必须重写。

+0

第一个查询在SQLite中不起作用。 –

+0

对不起,我错过了sqlite标记,但是如果您有一个名为MustAppear的永久表,并且具有所需的类别,则不需要WITH子句,并且应该可以毫无困难地使用第一个查询的正文。 –