Mysql SQL Select语句重复

Mysql SQL Select语句重复,mysql,sql,Mysql,Sql,我有三个SQL表(Movies、MovieCopy和RentalTransactions)。Movies保存有关电影的数据,MovieCopy保存与特定DVD等拷贝数相关的数据,并用作电影和RentalTransactions之间的关联实体,RentalTransactions保存有关电影租赁的数据 电影有10行数据(电影1、电影2、电影3等,最多10行)。MovieCopy有30行,这30行由电影表中10部电影的3份副本组成。RentalTransactions有10行,与MovieCopy中

我有三个SQL表(Movies、MovieCopy和RentalTransactions)。Movies保存有关电影的数据,MovieCopy保存与特定DVD等拷贝数相关的数据,并用作电影和RentalTransactions之间的关联实体,RentalTransactions保存有关电影租赁的数据

电影有10行数据(电影1、电影2、电影3等,最多10行)。MovieCopy有30行,这30行由电影表中10部电影的3份副本组成。RentalTransactions有10行,与MovieCopy中的前10行相关

我正在尝试运行一个报告,该报告将向我显示当前未借出的所有“DVD”类型的电影,因此这将是MovieCopy表中剩余的20份电影

下面是我尝试拉取此报告的SQL代码,但当我执行此SQL时,返回290行,我不确定为什么会发生这种情况,理想情况下,我只希望看到MovieCopy中不在RentalTransactions中的20行

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;
选择Movies.Movie\u名称、Movies.Movie\u类型、,
Movies.Movie\u介质,将(MovieCopy.Movie\u CopyID)计数为副本
来自电影、电影拷贝、租赁交易
其中Movies.Movie_media='DVD'和Movies.MovieID=MovieCopy.MovieID
和MovieCopy.Movie_CopyID RentalTransactions.Movie_CopyID;

有人能看到我的错误吗?

使用
不存在
删除
电影拷贝
中存在
租赁交易
的所有行,并使用
分组方式
获取每部电影的计数器

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 );
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

你的桌子结构不对。您正在使用RentalTransactions中存在的条目作为是否租用副本的标志。但是,当您执行查询时,这并不像您期望的那样有效。该查询将查找电影类型为“DVD”且在MovieCopy中有相应条目的所有情况,但对于不是其本身的每个事务。这将创建重复项

此外,这将迫使您在每次有人返回电影副本时删除条目,这将破坏任何形式的历史


您需要的是在MovieCopy中创建一个新属性,并根据副本是否租用将其设置为true/false。

这是一个有点复杂的查询。你的版本似乎有三个缺陷。第一个是表名的使用不一致,例如
from
子句中的
Transactions
,以及
RentalTransactions
作为别名。第二种是使用旧式联接。第三个是不一致地使用
group by

因为表述查询的一种方法是使用
左外部联接
,所以旧式隐式联接是一个真正的问题

逻辑是根据媒体过滤电影。然后,将外部联接保留到出租表,并只选择没有出租记录的副本

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;
你可以这样做

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行来自电影复制表

如何根据是否租用将其设置为true/false?我猜知道它是否被租用的唯一方法是RentalTransactions中是否存在MovieCopy_ID?当事件发生时,您可以使用更新查询修改适当MovieCopy的标志并将其设置为true/false。您需要更改表以添加新列。正如我所说的,从技术上讲,你正在做的事情是可行的,但它有很大的缺点。值得注意的是,您必须删除以前的租用,才能再次租用该电影副本。这使得不可能保留历史。您必须首先在单独的“TransactionHistory”表中创建数据的副本,然后删除前一个表中的数据。