SQL查询以返回与任何或所有筛选器匹配但不超过筛选器的行

SQL查询以返回与任何或所有筛选器匹配但不超过筛选器的行,sql,tsql,Sql,Tsql,我尝试做的一个简化场景是: 我有一个表示筛选器的单列表 我想从一个表中进行选择,只包括连接到与一个或多个筛选器值匹配的表上的行,但也排除存在筛选器中不存在的值的结果 我在这里想要的结果是 MovieA MovieB 有人能帮我解答这个问题吗 CREATE TABLE [Movie] (Name VARCHAR(100) NOT NULL) CREATE TABLE [Actor] (Name VARCHAR(100) NOT NULL) CREATE TABLE [Character] (Na

我尝试做的一个简化场景是:

我有一个表示筛选器的单列表

我想从一个表中进行选择,只包括连接到与一个或多个筛选器值匹配的表上的行,但也排除存在筛选器中不存在的值的结果

我在这里想要的结果是

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

您可以使用
分组依据
拥有

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)

编辑:

我想我误解了原来的问题。以下内容可确保所有参与者都在参与者列表中:

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) ;

是一个SQL Fiddle。

您可以仅从字符和筛选器表派生它

|  Movie |
|--------|
| MovieA |
| MovieB |

这将返回MovieA和MovieC。应该归还的是电影A和电影B。MovieC有Sally在里面,而她不在过滤器里。
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) 
|  Movie |
|--------|
| MovieA |
| MovieB |