我有2张桌子(电影和手表)。
我想知道有多少人正在观看哪些电影。
我这样做了:
SELECT movieID, count(persID) FROM watch GROUP BY persID;
这基本上给了我我想要的东西。唯一的问题是,没有任何人观看的电影不会以0观众的身份显示在我的结果表中,但它们被排除在外了。
我想通过两种不同的方式来实现这一目标。使用UNION,另一种方式使用子查询。
答案 0 :(得分:1)
因此,您可以获得正在观看的电影列表和计数器-左将其加入所有电影列表:
SELECT * FROM
Movies m
LEFT JOIN
(select movieID, count(persID) as countwatch from watch group by persID) w
ON m.movieid = w.movieid
左加入意味着您可以获取所有电影,并且仅与正在观看的电影相关联。如果未观看电影,则其countwatch列将为
如果要将空值转换为0,请使用COALESCE:
SELECT m.*, COALESCE(w.countwatch, 0) as countwatch FROM
Movies m
LEFT JOIN
(select movieID, count(persID) as countwatch from watch group by persID) w
ON m.movieid = w.movieid
我们可以使用很多方法来执行此查询,但是我特别选择了这种方式,因为它基于您已经知道的内容,并概述了如何在子级别上对数据进行分组和汇总,然后将其连接到外层更多数据
它还很有用,因为您可能想在销售表中添加一些额外的数据,例如以了解正在观看的电影是收入最高的电影。如果选择Salman的路线(在此情况下正确),则在添加更多表时会遇到统计信息问题,因为行数的乘积会超出您的预期。通过将销售和观看分组,例如,您可以将它们连接到主表,而不会导致行重复(也称为笛卡尔乘积)。因此,对于这种性质的查询,我倾向于建议在子查询中进行分组和聚合,然后再加入其他表,以保持主表(电影)与子查询的输出(例如观看,销售,演员人数)之间的1:1关系。 ,等等)包含与主要电影相关但彼此之间不一定相关的数据
答案 1 :(得分:0)
尝试这样做
select movie.title, count(watch.persID)
from movies left outer join watch on movies.id = watch.movieID
group by movieID;
我认为它可以工作
答案 2 :(得分:0)
由于您坚持使用UNION和子查询,因此下面的答案将同时使用:
SELECT movieID, COUNT(*) AS watchCount
FROM watch
GROUP BY movieID
UNION
SELECT movieID, 0
FROM movies
WHERE movieID NOT IN (
SELECT movieID
FROM watch
WHERE movieID IS NOT NULL
)
答案 3 :(得分:0)
仅使用UNION:
SELECT movieID, COUNT(*) -1 AS watchCount -- subtract the movie row
FROM
(
SELECT movieID -- multiple rows per watched movie
FROM watch
UNION ALL
SELECT movieID -- exactly one row per movie
FROM movies
)
或(如果要监视的行很多,可能会更快)
SELECT movieID, max(cnt)
FROM
(
SELECT movieID, count(*) as cnt
FROM watch
GROUP BY movieID
UNION ALL
SELECT movieID, 0
FROM movies
)
GROUP BY movieID