【发布时间】:2019-06-05 10:15:34
【问题描述】:
作为一名 SQL 外行,我在斯坦福的 SQL 课程中做一些数据修改查询以进行练习。最后一个练习对我来说有点棘手,尽管我设法使用 IN 运算符完成了它。作为一个小插件,我尝试使用 EXISTS 为子查询重写查询。事实证明这比预期的要难,所以现在我想知道是否有更优雅的方法。
大约是第 4 季度:“删除电影年份在 1970 年之前或 2000 年之后且评分低于 4 星的所有评分。”
SQL fiddle 可以在这里找到:http://www.sqlfiddle.com/#!9/f7f3ad
非常感谢您!
我首先尝试将附加的 AND 语句拖到子查询中,然后仅将 IN 替换为 EXISTS。不久之后,我发现这实际上会删除整个表,因为 Exists 子句将评估为 true,而无需任何外部表的引用。
意识到这一点后,我尝试在外部表中使用别名,以便能够从内部明确引用外部表。但是,系统不允许我这样做。我相信他们正在运行 Postgres,而我们在 Uni 使用 MySQL。你知道MySQL是否允许在数据修改语句中使用别名吗?
现在是查询本身。它在我看来相当冗长。使用 EXISTS 有没有更聪明的方法来解决这个问题?或者可能是完全不同的东西,根本不依赖 IN / Exists。
使用 IN:
Delete
FROM Rating
Where MId IN
(
/*movies either before 1970 or after 2000*/
Select r.MId
FROM Movie as m
INNER JOIN Rating as r
on m.MId = r.MId
WHERE m.year <1970 Or m.year > 2000
)
-- pick those with less than 4 stars
AND stars < 4;
使用存在:
Delete
FROM Rating
Where EXISTS(
Select *
FROM Movie as m
INNER JOIN Rating as r
on m.MId = r.MId
WHERE (m.year <1970 Or m.year > 2000) AND r.stars < 4
AND Rating.rId = r.RId AND Rating.Mid = r.MId AND Rating.stars <4
);
让我苦苦挣扎的一件事是我检查外部表中的星号是否小于 4 的最后一点。对我来说,看起来我只是在连接条件内完成整个查询的工作。但是,我发现忽略它实际上会删除所有 rId 为 201 的评级,因为它发现第一个 201 元组符合标准(在日期范围之外,小于 4 星)并得出结论,因为它存在,它也可以删除另一个元组(其中的星星实际上 >= 4)
【问题讨论】:
标签: mysql sql sql-delete exists in-operator