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 |