SQL-如何编写返回的查询

问题描述 投票:0回答:2

我有一个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”以及如何计算其他观众观看过多少部同类电影。

谢谢

sql postgresql
2个回答
0
投票

嗯。这很棘手。

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中是唯一的。


0
投票

我想出了一个使用横向连接的解决方案,以获得从子查询中观看的普通电影的数量。亚历克斯观看的电影的数量也在子查询中获取。它们都与(不同的)查看器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看到它的行动。

© www.soinside.com 2019 - 2024. All rights reserved.