0

我们有用户、问题和无限级别的类别。用户可以从问题中获得一些分数。问题可以有多个类别。

我想做的是计算每个类别的顶级用户:它只是从该类别下的问题中获取的总分,它也是子类别。

所以,我有这些表:

questions
--------------
id
title
question

categories
--------------
id
parent_id
category
lft
rgt

question_categories
--------------
question_id
category_id

users
--------------
id
username

user_points
--------------
id
user_id
question_id
point_type
points

user_category
--------------
user_id
category_id
points    

我想做的是计算 user_category.points 值。总结每个类别的分数很容易,但包括子类别变得越来越复杂。

最好的方法是什么?

示例计算:

假设类别是:

Programming
   PHP
      Zend Framework
      Symfony
   Java
   Ruby on Rails

假设用户从 Zend Framework获得3 分,从 PHP获得2 分,从 java获得5 分,从 Rails获得1 分。该用户每个类别的积分将是:

Programming            11 (5+5+1)
   PHP                  5 (2+3)
      Zend Framework    3
      Symfony
   Java                 5
   Ruby on Rails        1
4

4 回答 4

1

也许最好使用标签而不是层次结构。例如,任何带有“Zend Framework”的东西也会有“PHP”和“Programming”标签。当某些类别可以出现在多个位置时,这也很有帮助。例如,我可以在 jQuery 和 Javascript 中使用 ajax。然后,将 1 添加到用户类别中列出的每个标签。

于 2012-07-16T20:47:07.437 回答
0

我将创建一个user_categories表,在其中存储 3 个值user_idcategory_iduser_score。它很容易维护(只需要INSERTor UPDATE),也很容易查询每个类别的顶级用户。

于 2012-07-16T20:45:28.490 回答
0

如果您只想对每个顶级类别求和,那么您应该在您的类别表中添加一个名为 root_id 的字段(保存该类别的传递父项的 id)。

那么您的总和将计算为:

select up.user_id, ctg.root_id, sum(up.points)
from user_points up
join question_categories qc on up.question_id = qc.question_id
join categories ctg on qc.category_id = ctg.id
group by up.user_id, ctg.root_id
于 2012-07-16T21:07:30.140 回答
0

这个 php 和 SQL 应该为您提供每个类别的前 3 名用户,包括子类别:

$query = "SELECT id, parent_id FROM categories";
$parent = array();
...fetch mysql data loop depending on what connection you use, mysqli or pdo...
{
   $parent[$result['id']] = $result['parent_id'];
}

$childs = array();

foreach($parent as $id => $parrent_id)
{
   $childs[$parrent_id][$id] = $id;
   $next_parrent_id = $parrent_id;
   while($next_parrent_id = $parent[$next_parrent_id])
   {
      $childs[$next_parrent_id][$id] = $id;
   }
}

foreach($parent as $id => $parrent_id)
{
   $current_categories = array($id => $id) + $childs[$id];
   $query = "SELECT user_id, username, SUM(points) AS total_points
             FROM user_points 
             LEFT JOIN users ON (user_id = users.id)
             LEFT JOIN question_categories USING (question_id)
             WHERE category_id IN (" . implode(', ', $current_categories). ")
             ORDER BY total_points DESC
             LIMIT 3";
   ...fetch mysql data loop...
}
于 2012-07-16T21:18:21.427 回答