我有三张桌子。变化,讨论和对话。每个讨论都有一系列对话。每次谈话都是关于改变的。然后,对话在讨论中排名1-10。你最终会得到这样的东西:
Conversations{
[ id: 1, discussion_id: 1, change_id 1, rank: 1 ],
[ id: 1, discussion_id: 1, change_id 3, rank: 3 ],
[ id: 1, discussion_id: 1, change_id 5, rank: 2 ],
[ id: 1, discussion_id: 1, change_id 2, rank: 4 ],
[ id: 1, discussion_id: 1, change_id 4, rank: 5 ],
[ id: 1, discussion_id: 2, change_id 3, rank: 1 ],
[ id: 1, discussion_id: 2, change_id 2, rank: 2 ],
[ id: 1, discussion_id: 2, change_id 4, rank: 5 ],
[ id: 1, discussion_id: 2, change_id 5, rank: 3 ],
[ id: 1, discussion_id: 2, change_id 1, rank: 4 ]
}
我想找到最高的得分变化。当我想出这个问题时,我以为我已经这样做了:
SELECT changes.*, SUM(conversations.rank) AS score FROM "changes"
INNER JOIN "conversations" ON "conversations"."change_id" = "changes"."id"
GROUP BY changes.id
这增加了所有等级。这意味着越低越好。然而,这个相当原始的解决方案有其缺陷:如果你给一个更改排名1和3,它将得到相同的分数,就像你用4对一个变化进行排名一样。
也许要解决这个问题,你可以做得更好更好:第一名= 5分,第二名= 4分,等等。我不知道如何实现这一点。它也可能不是最好的方法。
Here你可以找到一个上下文的SQL小提琴。仅仅是一个FYI:我正在以积极的记录这样做。我用这个生成了查询:
Change.select("changes.*, SUM(conversations.rank) as conversations_rank").group("changes.id").joins(:conversations)
答案 0 :(得分:0)
我想出了两种方法。两者都很简单。我只是有点傻了:)
第一个,也可能是最简单的一个:
SELECT changes.name, SUM(11 - conversations.rank) as score FROM "changes"
INNER JOIN "conversations"
ON "conversations"."change_id" = "changes"."id"
GROUP BY changes.id
ORDER BY score desc
简单的数学呃。因此,如果conversations.rank = 1,那么它将是10,因为1减11是10。
或许更好的方法是使用另一张表:
CREATE TABLE ranks (
rank INT UNSIGNED PRIMARY KEY,
value INT UNSIGNED
);
INSERT INTO ranks
VALUES (1, 5),
(2, 4),
(3, 3),
(4, 2),
(5, 1);
然后在conversations.rank上进行联接排名:
SELECT changes.name, SUM(ranks.value) as score FROM "changes"
INNER JOIN "conversations"
ON conversations.change_id = changes.id
INNER JOIN "ranks"
ON conversations.rank = r.rank
GROUP BY changes.name;
感谢您的帮助。