0

我有一个电影列表,用户可以使用 jQuery UI Sortable 对他们最喜欢的电影进行排序(一切都很好)。序号越低,薄膜 (1) 越好,而序号越高 (26) 越差。电影列表可能无穷无尽,但在数据库中是固定的(用户无法添加更多),因此用户只能从 x 电影列表中选择。

电影不必在用户列表中,如果他们没有看过电影 5,那么它不会被包括在内(这可能会使问题更加复杂)。

目前,这存储在表中:

film_id | user_id | order
4         2         3
5         3         3
6         2         1
7         2         2
7         3         1 
8         3         2

我想要的,但不知道从哪里开始是一个整体的“前 10 名”风格列表。ie 电影 7 是最受欢迎的,因为它在人们的名单中出现得更高,并且在更多的名单中。电影 6 可能是最受欢迎的,但它只在一个列表中?!

我被困在逻辑和Mysql查询上!

我在想我可能需要以某种方式加权订单?或者有一个单独的表格,其中包含每部电影的得分,并在每次编辑后更新它。如果以下查询仅基于表中项目的计数而不是当我想将位置添加到等式中时,它似乎是正确的想法。

SELECT ff.film_id, COUNT(ff.film_id) AS cnt, SUM(ff.order) AS rank FROM
`favourite_film` AS ff GROUP BY ff.film_id ORDER BY cnt DESC, rank ASC

我想我需要计算表中所有电影的数量和顺序的总和(但反过来?),然后我的理论就变得平淡了!

任何帮助或链接将不胜感激。谢谢。

4

4 回答 4

0

您应该在保存之前还原列表。这样您就可以将未选择的电影排除在评级之外。

一种解决方法可能是:

计算列表的数量SELECT COUNT(DISTINCT(user_id)另存为$AMOUNT_OF_LISTS

现在使用

SELECT film_id, (SUM(order)+($AMOUNT_OF_LISTS-COUNT(DISTINCT(user_id)))*POINTS_FOR_NOT_IN_LIST) as points FROM table GROUP BY film_id

逻辑:总结所有点并POINTS_FOR_NOT_IN_LIST为每次不在列表中添加点(列表总数 - 电影在列表中的次数)

插入POINTS_FOR_NOT_IN_LIST您喜欢的值。(可能是 26 或 27 甚至更低)

您可能想要添加ORDER BY points DESC LIMIT 10到查询中以获得 10 个最高点

于 2013-08-16T13:11:27.870 回答
0
SELECT MIN(  `order` ) , COUNT( * ) AS cnt,  `film_id` 
FROM  `favourite_film` 
GROUP BY  `film_id` 
ORDER BY cnt DESC ,  `order` 
于 2013-08-16T13:19:01.680 回答
0

我会这样做,我会为排名较高的电影分配更高的价值。然后我会将每部电影的值和按总降序的顺序相加,以获得总体排名。这样,您就可以对每部电影的受欢迎程度和排名给予重视。

因此,如果您想通过每个用户排名前 3 的电影来做到这一点,您可以这样做:

SELECT  film_id, SUM(3         -- The max number of ranked movies per user
                     - order   -- the ranking
                     + 1) total_score

FROM    TABLE_NAME

GROUP BY film_id

ORDER BY total_score DESC;

显然你可以删除评论

这样,评分最高的电影将获得更高的分数、次高的、次高的分数等。如果您计算每位用户的前 10 部电影,只需将 3 更改为 10。

于 2013-08-16T13:19:04.483 回答
0

根据您的“业务规则”,我认为您应该找到某种计算来同时考虑位置“投票”数量。

只是一个随机猜测,但为什么不排序COUNT(votes)/AVG(pos)呢?出于可维护性的原因,您可能需要考虑排名函数:

CREATE FUNCTION ranking(average_pos REAL, vote_count INT)
RETURNS REAL
DETERMINISTIC
  RETURN vote_count/average_pos;

现在的查询很简单:

SELECT film_id,
       AVG(pos) as a, COUNT(*) as c, ranking(AVG(pos),COUNT(*)) AS rank
  FROM vote GROUP BY film_id
  ORDER BY ranking(AVG(pos), COUNT(*)) DESC;

用你的例子生产:

+----------+------+----+----------------+
| FILM_ID  |  A   | C  |      RANK      |
+----------+------+----+----------------+
|       7  | 1.5  | 2  | 1.333333333333 |
|       6  | 1    | 1  | 1              |
|       8  | 2    | 1  | 0.5            |
|       5  | 3    | 1  | 0.333333333333 |
|       4  | 3    | 1  | 0.333333333333 |
+----------+------+----+----------------+

http://sqlfiddle.com/#!2/3b1d9/1

于 2013-08-16T13:25:17.643 回答