我有以下表格:
copy(movie_id,copy_id)
rented(copy_id,outdate,returndate)如果租出电影,则在数据库中将返回日期设置为null。
同一部电影将有多份拷贝。对于单个movie_id,我们可以有多个copy_id。
我需要检索已完全租出的电影,即电影的所有拷贝都已租出或以另一种方式放置--电影的所有副本都在租用表中,返回日期设置为null。
我尝试过内部连接,但无法将复制表中的所有元组与租用表关联起来。
每个副本都有一个全局唯一的copy_id。因此,两部不同电影的拷贝不能有相同的copy_id。
如果该拷贝从未被出租,它将不会出现在列表中,但这意味着该电影仍然是库存,因为它从来没有被租用。这个不应该出现。
同样的电影和拷贝一定会出现在租用多次,如果它已被租用不止一次。
发布于 2014-10-14 19:23:18
结果比我想象的要难一些。我相信这是正确的答案。
所有的电影,所有的拷贝都有租来的,退货日期为空
在数学表示法(A=for All,E=there存在):
{m:m=(A,c:C: c.movie_id = m.movie_id @(E: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)发布于 2014-10-14 21:07:46
您可以通过使用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)发布于 2014-10-14 19:23:02
您可以按movie_id分组并计数返回日期为空的位置:
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) = 0https://stackoverflow.com/questions/26368571
复制相似问题