我尝试做的简化方案是:
我有一个代表过滤器的列表。
我想从一个表中进行选择,只包含连接到一个匹配一个或多个过滤器值的表的行,但也排除在过滤器中不存在值的结果。
例如:我想要的结果是
MovieA
MovieB
任何人都可以帮忙解决问题。
CREATE TABLE [Movie] (Name VARCHAR(100) NOT NULL)
CREATE TABLE [Actor] (Name VARCHAR(100) NOT NULL)
CREATE TABLE [Character] (Name VARCHAR(100) NOT NULL, Movie VARCHAR(100) NOT NULL, Actor VARCHAR(100) NOT NULL)
INSERT INTO Movie (Name) VALUES ('MovieA'), ('MovieB'), ('MovieC')
INSERT INTO Actor (Name) VALUES ('Bob'), ('Fred'), ('Sally')
INSERT INTO [Character] (Name, Movie, Actor) VALUES ('BobA', 'MovieA', 'Bob')
INSERT INTO [Character] (Name, Movie, Actor) VALUES ('BobB', 'MovieB', 'Bob')
INSERT INTO [Character] (Name, Movie, Actor) VALUES ('BobC', 'MovieC', 'Bob')
INSERT INTO [Character] (Name, Movie, Actor) VALUES ('FredA', 'MovieA', 'Fred')
INSERT INTO [Character] (Name, Movie, Actor) VALUES ('FredC', 'MovieC', 'Fred')
INSERT INTO [Character] (Name, Movie, Actor) VALUES ('SallyC', 'MovieC', 'Sally')
CREATE TYPE [Names] AS TABLE([Name] VARCHAR(100) NOT NULL)
DECLARE @ActorNamesFilter dbo.Names
INSERT INTO @ActorNamesFilter (Name) VALUES ('Bob'), ('Fred')
-- I want to return all movies that include *any* of the above actors but exclude movies that have other actors in them.
SELECT m.Name
FROM [Character] c
INNER JOIN Movie m ON c.Movie = m.Name
LEFT OUTER JOIN Actor a ON c.Actor = a.Name
LEFT OUTER JOIN @ActorNamesFilter filter ON a.Name = filter.Name
答案 0 :(得分:1)
你可以从Character& amp;过滤表Demo
SELECT
Character.Movie
FROM Character
LEFT JOIN ActorNamesFilter filter ON Character.Actor = filter.Name
GROUP BY
Character.Movie
HAVING COUNT(DISTINCT Character.Actor) = COUNT(DISTINCT filter.name)
<强> Results 强>:
| Movie |
|--------|
| MovieA |
| MovieB |
答案 1 :(得分:0)
您可以使用group by
和having
:
SELECT m.Name
FROM [Character] c INNER JOIN
Movie m
ON c.Movie = m.Name JOIN
Actor a
ON c.Actor = a.Name JOIN
@ActorNamesFilter filter
ON a.Name = filter.Name
GROUP BY m.Name
HAVING COUNT(*) = (SELECT COUNT(*) FROM @ActorNamesFilter);
这会计算影片中的演员数量,然后检查匹配数量是否与过滤器中的名称数量相同。
作为注释:如果演员可以播放多个角色,那么这应该使用count(distinct)
:
HAVING COUNT(DISTINCT a.Name) = (SELECT COUNT(*) FROM @ActorNamesFilter);
编辑:
我想我误解了原来的问题。以下内容确保所有actor都明确地位于actor列表中:
SELECT m.Name
FROM [Character] c LEFT JOIN
Movie m
ON c.Movie = m.Name LEFT JOIN
Actor a
ON c.Actor = a.Name LEFT JOIN
@ActorNamesFilter filter
ON a.Name = filter.Name
GROUP BY m.Name
HAVING COUNT(*) = COUNT(filter.name) ;
Here是一个SQL小提琴。