SQL实现:筛选在所有影片发行年份均有参与创作的电影创作者
业务查询逻辑问题与修正方案
基础表说明
Filme:影片表Cineasti:电影创作者表Premii_obtinute:获奖记录关联表
注:表结构参考配套配图说明,无外部跳转链接
业务需求
筛选在所有影片发行年份范围内,均有参与影片制作的电影创作者。
提交的尝试代码存在的核心问题
三版查询均无法输出正确结果,核心问题包括:
- 逻辑链路偏差:通过获奖表的INNER JOIN关联创作者与影片,仅能统计有获奖记录的参与场景,无获奖记录的参与条目会被完全过滤,统计结果失真
- 语法硬伤:第二版查询缺失最开头的
SELECT子句,无法正常解析执行 - 匹配方式存在缺陷:通过拼接
numecineast || ' - ' || year字符串做存在性校验,一旦字段内容包含特殊分隔符,就会出现匹配错位,且全字符串扫描的执行效率极低 - 笛卡尔积未做去重:交叉连接创作者列表与年份列表时,未对两边的数据集做去重处理,生成的匹配对存在大量重复,最终EXCEPT的运算结果存在逻辑偏差
正确实现方案
这类“覆盖所有枚举值”的查询,可通过直观的等值校验逻辑实现:某创作者参与过的不重复发行年份数量,等于全库所有不重复影片发行年份的总数量,即可说明该创作者在所有发行年份都有参与作品。
参考实现代码如下:
WITH all_year_stat AS ( -- 统计全库维度的不重复影片发行年份总数 SELECT COUNT(DISTINCT AnLansare) AS total_year_count FROM Filme ), creator_year_stat AS ( -- 统计单个创作者参与过的不重复发行年份数量 SELECT c.codcineast, c.numecineast, COUNT(DISTINCT f.AnLansare) AS joined_year_count FROM Cineasti c -- 按实际表关联关系连接创作者与参与的影片 INNER JOIN Premii_obtinute p ON c.codcineast = p.codcineast INNER JOIN Filme f ON p.codfilm = f.codfilm GROUP BY c.codcineast, c.numecineast ) -- 筛选年份覆盖度与全库总年份数一致的创作者 SELECT cys.numecineast FROM creator_year_stat cys CROSS JOIN all_year_stat ays WHERE cys.joined_year_count = ays.total_year_count;
基于EXCEPT思路的修正写法
如果希望保留原有的EXCEPT实现逻辑,可修正原代码中的关联逻辑与匹配方式,核心是用NOT EXISTS替代字符串拼接的校验:
SELECT numecineast FROM Cineasti EXCEPT SELECT c.numecineast FROM Cineasti c CROSS JOIN (SELECT DISTINCT AnLansare FROM Filme) all_release_year WHERE NOT EXISTS ( SELECT 1 FROM Premii_obtinute p INNER JOIN Filme f ON p.codfilm = f.codfilm WHERE p.codcineast = c.codcineast AND f.AnLansare = all_release_year.AnLansare );
该写法的逻辑为:先取全量创作者列表,再排除“存在某一个发行年份,该创作者完全没有参与对应影片”的主体,剩余结果即为满足需求的创作者。
内容的提问来源于stack exchange,提问作者Eisotopius
相关产品推荐
相关产品推荐

