计算模式中多个列之间不同的项目出现次数

时间:2015-07-09 13:24:07

标签: php mysql

我正在使用MySql和PHP开发一个调查应用程序 答复将采用以下格式:

+-c1_1-+-c1_2-+-c1_3-+-c1_1-+-c1_2-+-c1_3-+-....
+ red  + blue + pink + cyan + red  + gray + ....
+ black+ pink + plum + red  + blue + gray + ....
+ cyan + red  + blue + blue + pink + plum + ....
+------+------+------+------+------+------+ ....
  • c1_1代表Column_For_Question_1_With_Rank_1
  • c1_2代表Column_For_Question_1_With_Rank_2
  • c1_3表示Column_For_Question_1_With_Rank_3
  • c2_1代表Column_For_Question_2_With_Rank_1
  • c2_2代表Column_For_Question_2_With_Rank_2
  • c2_3表示Column_For_Question_2_With_Rank_3

评分是这样的:

  • 等级1 =列cX_1中的颜色=得到3个标记​​(c1_1,c2_1,c3_1 ..)
  • 等级2 =列cX_2中的颜色=获得2个标记(c1_2,c2_2,c3_2 ..)
  • 等级3 =列cX_3中的颜色=获得1分(c1_3,c2_3,c3_3 ..)

红色分数:

  • 出现在cX_1两次= 3x2 = 6
  • 在cX_2中出现两次= 2x2 = 4
  • 所以Red得分为6 + 4 = 10

蓝色分数:

  • 一次出现在cX_1 = 3x1 = 3
  • 在cX_2中出现两次= 2x2 = 4
  • 出现在cX_3中两次= 1x2 = 2
  • 所以蓝色得分为3 + 4 + 2 = 9

是否可以编写有效的查询来获得如下结果:

+-color-+-score-+
+  red  +  10   +
+ blue  +   9   +
+  xxx  +   #   +
+  xxx  +   #   +
+  xxx  +   #   +
+-------+-------+

如果无法做到这一点,至少会出现以下情况:

+-color-+-n_cX_1-+-n_cX_2-+-n_cX_3-+
+  red  +   2    +   2    +   0    +
+ blue  +   1    +   2    +   2    +
+  xxx  +   #    +   #    +   #    +
+  xxx  +   #    +   #    +   #    +
+  xxx  +   #    +   #    +   #    +
+  xxx  +   #    +   #    +   #    +
+-------+--------+--------+--------+

实际上颜色会被人名取代。

每组三个连续的列' (cX_1,cX_2,cX_3)表示针对9个问题中的每一个评定的第一,第二和第三等级。所以会有3x9 = 27列

有人可以帮我这个吗?我正在考虑反复使用count(*),但我确信这是一种错误的方法。在发布之前搜索了很多但无法解决它。

编辑1: 想要提及的是,这些列中可能有近50个人的名字。每行代表一位进行调查的审查员的回复。将有大约100名这样的审查员,因此大约有100行。

2 个答案:

答案 0 :(得分:0)

这是我的解决方案,我更多地使用PHP,所以我的答案将是PHP方面,如果你想要SQL解决方案,你应该等待一段时间让另一个用户添加SQL端解决方案,

你将从MySQL获得PHP中的这种数组,

$result = [
    'c1_1'=>['red','black','cyan'],
    'c1_2'=>['blue','pink','red'],
    'c1_3'=>['pink','plum','blue'],
    'c2_1'=>['cyan','red','blue'],
    'c2_2'=>['red','blue','pink'],
    'c2_3'=>['gray','gray','plum']
];

现在,生成一个用户数组,其中包含每个用户在每个类别中的成就

$users = [];

foreach($result as $k => $v)
{
    foreach($v as $user)
    {
        $users[$user][] = $k;
    }
}

现在,$ users数组看起来像,

array (size=7)
  'red' => 
    array (size=4)
      0 => string 'c1_1' (length=4)
      1 => string 'c1_2' (length=4)
      2 => string 'c2_1' (length=4)
      3 => string 'c2_2' (length=4)
  'black' => 
    array (size=1)
      0 => string 'c1_1' (length=4)
  'cyan' => 
    array (size=2)
      0 => string 'c1_1' (length=4)
      1 => string 'c2_1' (length=4)
  'blue' => 
    array (size=4)
      0 => string 'c1_2' (length=4)
      1 => string 'c1_3' (length=4)
      2 => string 'c2_1' (length=4)
      3 => string 'c2_2' (length=4)
  'pink' => 
    array (size=3)
      0 => string 'c1_2' (length=4)
      1 => string 'c1_3' (length=4)
      2 => string 'c2_2' (length=4)
  'plum' => 
    array (size=2)
      0 => string 'c1_3' (length=4)
      1 => string 'c2_3' (length=4)
  'gray' => 
    array (size=2)
      0 => string 'c2_3' (length=4)
      1 => string 'c2_3' (length=4)

现在,通过我们刚刚生成的用户传递数组来定义一个计算标记的函数,

function marks_of($input)
{
    $marks_index = ['_1'=>3, '_2'=>2, '_3'=>1]; // define marks here
    $marks = 0;
    foreach($input as $marking)
    {
        $marks += $marks_index[substr($marking, -2)];
    }
    return $marks;
}

您需要在上面的代码中评论每个类别中的标记。

现在,请使用它,

$marks_of_red = marks_of($users['red']);

将给出

int 10

按名称生成包含每个用户标记的数组

$all_users_marks = [];

foreach($users as $name => $achievements)
{
    $all_users_marks[$name] = marks_of($users[$name]);
}

现在,$all_users_marks

array (size=7)
  'red' => int 10
  'black' => int 3
  'cyan' => int 6
  'blue' => int 8
  'pink' => int 5
  'plum' => int 2
  'gray' => int 2

正如我已经说过的,如果你想要MySQL侧面的答案,请等待某人。

答案 1 :(得分:0)

将表格规范化为:

question | rank | name

然后使用此查询获得总分:

SELECT name, SUM( 4 - rank ) score FROM mytable GROUP BY name ORDER BY score DESC