我有一个DB,它只是一个包含3列的表:viewer_id,movie_id,Ranking(INTEGER)(INTEGER)(TEXT)
此表中的一行表示某个观看者已观看某部电影。
我需要编写一个返回的查询:所有观众至少观看了75%的观众观看过的电影(让我们称他为亚历克斯)。
我成功地返回了所有观看与给定观看者相同电影的观众的所有ID:
SELECT otherss.viewer_id FROM
((SELECT viewer_id,movie_id FROM viewers_movies_rankings
WHERE viewer_id= 313) AS alex
INNER JOIN (SELECT viewer_id,movie_id FROM viewers_movies_rankings
WHERE viewer_id != 313) AS otherz
ON alex.movie_id = otherss.movie_id)
这段代码返回给定观众(亚历克斯)观看的电影数量:
SELECT COUNT (*) AS num FROM viewers_movies_rankings WHERE viewer_id = 313
我该如何完成此查询?我正在努力使用“group by”以及如何计算其他观众观看过多少部同类电影。
谢谢
嗯。这很棘手。
select vmr.viewer_id
from viewers_movies_rankings vmr cross join
(select count(*) as cnt
from viewers_movies_rankings vmr_alex
where vmr_alex.viewer_id = 313
) alex
where vmr.movie_id in (select vmr_alex.movie_id from viewers_movies_rankings vmr_alex where vmr_alex.viewer_id = 313)
group by vmr.viewer_id
having count(*) >= 0.75 * alex.cnt;
您可以在结果中过滤Alex,但检查是否返回了他/她是一个很好的测试。
注意:这假设观众/电影巴黎在viewers_movies_rankings
中是唯一的。
我想出了一个使用横向连接的解决方案,以获得从子查询中观看的普通电影的数量。亚历克斯观看的电影的数量也在子查询中获取。它们都与(不同的)查看器ID交叉连接。
我认为“Alex”本身不应该包括在结果中,并且一个人可以多次观看电影,但这对于百分比的计算毫无意义。
SELECT vmr.viewer_id
FROM (SELECT DISTINCT vmri.viewer_id
FROM viewers_movies_rankings vmri) vmr
CROSS JOIN (SELECT count(DISTINCT vmri.movie_id) c
FROM viewers_movies_rankings vmri
WHERE vmri.viewer_id = 313) a
CROSS JOIN LATERAL (SELECT count(DISTINCT vmri1.movie_id) c
FROM viewers_movies_rankings vmri1
INNER JOIN viewers_movies_rankings vmri2
ON vmri2.movie_id = vmri1.movie_id
WHERE vmri1.viewer_id = 313
AND vmri2.viewer_id = vmr.viewer_id) x
WHERE x.c::decimal / a.c::decimal >= .75
AND vmr.viewer_id <> 313;
在this SQL Fiddle看到它的行动。