我有以下表格:
copy(movie_id,copy_id)
rented(copy_id,outdate,returndate)
如果租借电影,则在数据库中将returnsndate设置为null。
同一部电影会有多个副本。对于单个movie_id,我们可以有多个copy_id。
我需要检索已完全租借的电影,即电影的所有副本都已租出或以其他方式放置 - 电影的所有副本都出现在租借的表格中,并且返回设置为空。
我尝试了内部联接,但无法将副本表中的所有元组与租用的表相关联。
每个副本都有一个全局唯一的copy_id。因此,2个不同电影的副本不能具有相同的copy_id。
如果从未租借过该副本,它将不会显示在列表中,但这意味着该电影仍然有库存,因为它从未被租用过。这不应该出现。
如果多次租借,同一部电影和副本肯定会多次出租。
答案 0 :(得分:1)
这比我想象的要困难一些。我相信这是正确的答案。
“所有电影的所有电影都存在租用的地方,其中返回者为空”
在数学符号中(A =全部,E =存在):
{m:M | (A c:C | c.movie_id = m.movie_id @(E r:R | r.copy_id = c.copy_id @ r.returndate = null))@ m.movie_id}
可以改写为:
“所有不存在副本的电影,其中不存在租用的地方,其中返回为空”
转换为以下SQL。
SELECT DISTINCT m.movie_id
FROM Copy m
WHERE NOT EXISTS
(SELECT 1 FROM Copy c
WHERE c.movie_id = m.movie_id
AND NOT EXISTS
(SELECT 1 FROM Rented r
WHERE r.copy_id = c.copy_id
AND returndate IS NULL)
答案 1 :(得分:1)
您可以使用left join
和聚合having
子句来执行您想要的操作。然后,计算没有返回日期的记录数,并将其与副本数进行比较:
SELECT c.movie_id
FROM copy c LEFT JOIN
rented r
ON c.copy_id = r.copy_id
GROUP BY c.movie_id
HAVING SUM(r.returndate IS NULL) = COUNT(DISTINCT c.copy_id)
请注意使用SUM()
进行比较。这会计算值为" true"。
以上查询假设一次不能多次租借一份副本。一个合理的假设,但总是值得检查。另一个having
子句将此考虑在内:
HAVING count(distinct case when r.returndate is null then c.copy_id end) = count(distinct c.copy_id)
答案 2 :(得分:0)
您可以按movie_id进行分组,并计算returnsndate为null的位置:
SELECT DISTINCT movie_id
FROM copy
JOIN rented
ON copy.copy_id = rented.copy_id
GROUP BY copy.movie_id HAVING COUNT(rented.returndate IS NULL) = 0