我会提前说,并且出于对时间和网站的尊重 - 这 是一项家庭作业。 然而,我已经想到了并编写了一个解决方案,但由于我无法成功剖析或获得相关的第三方意见,我感到有点恼火其他地方是否实际上是一个好的。
说我有一个简单的电影参与信息表(人物,电影,人物与电影的关系)如下:
create table film
(
person_name varchar(48) not null,
film_title varchar(128) not null,
relation varchar(48) not null
);
-- { 'Mel Gibson', 'Braveheart', 'director' }
-- { 'Mel Gibson', 'Braveheart', 'cast' }
-- { 'Steven Spielberg', 'A.I.' , 'director' }
-- { 'Hilary Swank', 'Million Dollar Baby', 'cast' }
-- etc
数据库和表格不是由我创建或维护的,我只是从中查询信息。
我需要为他们指导的每部电影中的演员(在镜头前行动)制作一组人名。对于那些导演至少一部他们没有采取行动的电影的人,或那些没有指挥任何事情的人,这种情况应该不。
我的查询(据我所知,可以证明产生正确的结果集),瞧瞧:
(
select person_name
from film
where relation = 'director'
)
except
(
select person_name
from
(
(
select person_name, film_title
from film
where relation = 'director'
)
except
(
select person_name, film_title
from film
where relation = 'cast'
)
) as director_behind_camera_for_film
)
我想知道查询是否合理,或者我是否一直在想这个问题?如果是后者,请您提供更好的解决方案或解释?
不要太注意我在任何地方都使用字符串的事实(代理键可能已经被用过了) - 这是一个简化的例子,但它仍然证明了我的挑战。
答案 0 :(得分:4)
SELECT tmp.person_name FROM
(
SELECT person_name, film_title, COUNT(relationship) as cnt
FROM film
WHERE relationship IN ('cast', 'director')
GROUP BY person_name, film_title
) as tmp
GROUP BY person_name
HAVING SUM(cnt) = COUNT(cnt)*2
或
SELECT tmp.person_name FROM
(
SELECT person_name, film_title, COUNT(DISTINCT(relationship)) as cnt
FROM film
WHERE relationship IN ('cast', 'director')
GROUP BY person_name, film_title
) as tmp
GROUP BY person_name
HAVING SUM(cnt) = COUNT(cnt)*2
答案 1 :(得分:3)
“我需要为他们所导演的每部电影中的导演(在镜头前行动)制作一套人名。因此,对于导演至少一部电影的人来说,条件不适用他们没有采取行动,或者没有指挥任何事情的人。“
你的短语的后半部分(“或者没有指示任何东西的人”)不正确。
如果一个人X没有指示任何东西,那么X指导的一组电影是空集,并且可能已经向你解释了(如果没有,那么我现在正在做)通用量化(已经在ALL ...中投射了空集总是产生“真”。
因此,如果X根本没有指向任何东西,那么X确实是在“他指导的所有电影”中投射的,因此,X应该包含在结果集中。 (如果这不是要求的方式,则要求应明确说明。)
那就是说,我在Can all SQL queries be represented in Relational Algebra, Domain and Tuple relational calculus中解释了关系师的运作细节(这是你获得结果所需要的)。
主题是不同的(经理和员工,而不是导演和电影),但查询的性质完全相同:让我得到与所有Y的Z关系的X.
修改
后来我意识到存在一个“微小的”差异:在这个特定的导演,演员和电影的例子中,“所有Y”的集合本身“依赖于”正在考虑的特定X.这是一个额外的复杂性,超出了关系鸿沟的更典型应用范围。解决这个问题可能需要使用GROUP()左右构建与关系值属性的关系,但我还没有弄清楚细节(并且GROUP()之类的运算符不太可能是你讲座的一部分。) / p>
向任何被引导忽视问题特定方面的人道歉。
答案 2 :(得分:1)
这看起来好像应该有效,而且更标准的SQL:
select director.person_name
from film director
full outer join film actor
on director.person_name = actor.Person_name
and director.film_title= actor.film_title
where actor.relationship = 'cast'
and director.relationship = 'director'
and actor.person_name is not null
and director.person_name is not null