我有三个SQL表(Movies,MovieCopy和RentalTransactions)。电影保存有关电影的数据,MovieCopy保存与特定DVD等的副本数量相关的数据,并用作电影和RentalTransactions之间的关联实体,RentalTransactions保存有关电影租赁的数据。
电影有10行数据(Movie1,Movie2,Movie3等,最多10行)。 MovieCopy有30行,这30行由Movies表中10个电影中的每一个的3个副本组成。 RentalTransactions有10行,与MovieCopy中的前10行相关。
我正在尝试运行一份报告,该报告将向我展示目前尚未借出的所有“DVD”类型的电影,因此这将是MovieCopy表格中剩余的20部电影。
下面是我试图提取此报告的SQL代码,但是当我执行此SQL时,我返回了290行,我不确定为什么会发生这种情况,理想情况下我希望只看到MovieCopy中的20行不属于RentalTransactions。
Select Movies.Movie_Name, Movies.Movie_Type,
Movies.Movie_Medium, Count(MovieCopy.Movie_CopyID) as Copies
FROM Movies,MovieCopy,RentalTransactions
WHERE Movies.Movie_Medium = 'DVD' and Movies.MovieID = MovieCopy.MovieID
and MovieCopy.Movie_CopyID <> RentalTransactions.Movie_CopyID;
任何人都可以看到我的错误吗?
答案 0 :(得分:0)
Select Movies.Movie_Name, Movies.Movie_Type,
Movies.Movie_Medium, Count(MovieCopy.Movie_CopyID) as Copies
FROM Movies,MovieCopy,RentalTransactions
WHERE Movies.Movie_Medium = 'DVD' and Movies.MovieID = MovieCopy.MovieID
and MovieCopy.Movie_CopyID NOT IN (SELECT Movie_CopyID FROM RentalTransactions );
答案 1 :(得分:0)
使用NOT EXISTS
删除MovieCopy
存在RentalTransactions
的所有行,并GROUP BY
获取每部电影的计数器。
Select
Movies.Movie_Name, Movies.Movie_Type, Movies.Movie_Medium,
Count(1) as Copies
FROM Movies
JOIN MovieCopy ON ( MovieCopy.MovieId = Movies.MovieId )
WHERE Movies.Movie_Medium = 'DVD'
NOT EXISTS
(
SELECT 1
FROM RentalTransactions
WHERE RentalTransactions.Movie_CopyID = MovieCopy.Movie_CopyID
)
GROUP BY
Movies.Movie_Name, Movies.Movie_Type, Movies.Movie_Medium
答案 2 :(得分:0)
您的表格结构错误。您使用RentalTransactions中的条目作为要租借的副本的标志。但是,当您执行查询时,这不会按预期工作。查询将查找电影类型为“DVD”并且在MovieCopy中具有相应条目的所有情况,但对于每个不属于自身的事务。这将产生重复。
此外,这会强制您在每次有人返回电影副本时删除条目,这会破坏任何形式的历史记录。
您需要拥有的是在MovieCopy中创建一个新属性,并根据是否租用该副本将其设置为true / false。
答案 3 :(得分:0)
这是一个有点复杂的查询。你的版本似乎有三个缺陷。第一种是不一致地使用表名,例如Transactions
子句中的from
和RentalTransactions
作为别名。第二个是使用旧式连接。第三是group by
的使用不一致。
因为制定查询的一种方法是使用left outer join
,旧式隐式连接是一个真正的问题。
逻辑是根据媒体过滤电影。然后,左外连接到租赁表,只选择没有租赁记录的副本。
Select m.Movie_Name, m.Movie_Type,
m.Movie_Medium, Count(MovieCopy.Movie_CopyID) as Copies
FROM Movies m join
MovieCopyRental mcr
on m.MovieID = mc.MovieID and m.Movie_Medium = 'DVD' left outer join
RentalTransactions rt
on mcr.Movie_CopyID = rt.Movie_CopyID and
WHERE rt.Movie_CopyId is NULL
GROUP BY m.Movie_Name, m.Movie_Type, m.Movie_Medium;
如果您想要所有电影的列表,包括那些没有副本的电影,请将where
子句更改为条件聚合:
Select m.Movie_Name, m.Movie_Type, m.Movie_Medium,
count(*) as TotalCopies, sum(rt.Movie_CopyId is NULL) as RemainingCopies
FROM Movies m join
MovieCopyRental mcr
on m.MovieID = mc.MovieID and m.Movie_Medium = 'DVD' left outer join
RentalTransactions rt
on mcr.Movie_CopyID = rt.Movie_CopyID and
GROUP BY m.Movie_Name, m.Movie_Type, m.Movie_Medium;
答案 4 :(得分:0)
你可以这样做
select mov.movie_id , mov.movietitle , cpm.movie_id , cpm.movietitle from tbl_movies as mov
left join tbl_moviescopy as cpm on cpm.movie_id = mov.movie_id
where movie_type = 'DVD'
and movie_id not exists (select movie_id from rentaltransactions)
对不起,根据您的问题创建了我自己的字段名称。 但是希望它可以帮到你,这会产生4行,电影表中的2行和电影拷贝表中的2行