如何使用MySQL分别对列进行计数和分组?

如何使用MySQL分别对列进行计数和分组?,mysql,group-by,Mysql,Group By,我有一个调查申请,我正在结果页面上工作。对于每个问题,页面应显示提供的不同答案以及每个答案提供的次数 有些问题可以接受多个答案。例如,让我们假设以下是这样一个问题: 你感觉怎么样 好 坏的 好的 这意味着允许将好、坏和/或好的任何组合作为答案 假设调查结果如下: 调查1:好,坏和好 调查2:好,坏和好 调查3:好和坏 调查4:好和坏 调查5:良好 调查6:良好 调查7:良好 预期结果如下: 你感觉怎么样 好=7 坏=4 好的=2 我的代码提供 你感觉怎么样 好=3 坏=2 好=4

我有一个调查申请,我正在结果页面上工作。对于每个问题,页面应显示提供的不同答案以及每个答案提供的次数

有些问题可以接受多个答案。例如,让我们假设以下是这样一个问题:

  • 你感觉怎么样
    • 坏的
    • 好的
    这意味着允许将
    和/或
    的任何组合作为答案

    假设调查结果如下:

    • 调查1:
    • 调查2:
    • 调查3:
    • 调查4:
    • 调查5:
      良好
    • 调查6:
      良好
    • 调查7:
      良好
    预期结果如下:

  • 你感觉怎么样
    • 好=7
    • 坏=4
    • 好的=2
    我的代码提供

  • 你感觉怎么样
    • 好=3
    • 坏=2
    • 好=4
    • 好的=1
    • 坏=2
    • 好的=1
    此示例的数据库条目如下所示:

    问题数 问题 答复1 答复2 答复3 ... 1. 你感觉怎么样? 好 坏的 可以 1. 你感觉怎么样? 好 坏的 可以 1. 你感觉怎么样? 好 坏的 1. 你感觉怎么样? 好 坏的 1. 你感觉怎么样? 好 1. 你感觉怎么样? 好 1. 你感觉怎么样? 好
    这是一个可怕的数据库模式

    这在Perl中会容易得多

    my%counts\u by\u answer\u by\u qid;
    {
    我的$sql
    选择'questionNum',
    `回答1`、`answer2`、`answer3`、`answer4`、`answer5`、,
    `回答6`、`answer7`、`answer8`、`answer9`、`answer10``
    从`结果`
    其中'title`=?
    ';
    我的$sth=$dbh->prepare($sql);
    $sth->execute($title);
    while(my($questionNum,@answers)=$sth->fetchrow\u数组){
    ++$counts_by_answer_by_qid{$questionNum}{$}表示grep长度,@answers;
    }
    }
    {
    我的$sql
    选择不同的
    `问题编号`,
    `问题:`
    从`结果`
    其中'title`=?
    按'questionNum'排序`
    ';
    我的$sth=$dbh->prepare($sql);
    $sth->execute($title);
    while(my($questionNum,$question)=$sth->fetchrow\u数组){
    我的$counts_by_answer=$counts_by_answer_by_qid{$questionNum}/{};
    说“$questionNum.$question”;
    为了我的回答(
    排序{$counts\u by_answer->{$b}$counts\u by_answer->{$a}
    按键(%$counts\u by\u answer)
    ) {
    my$count=$counts\u by\u answer->{$answer};
    说“*$answer=$count”;
    }
    }
    }
    
    我知道您同时面临许多问题,但最好的答案解决了他在使用Perl时遇到的问题:


    这是一个可怕的数据库模式

    人们通常在应用程序级别做的事情比他们需要做的多得多,因为他们从来没有学会在数据库中做正确的事情(例如,最好用适当的SQL查询而不是Perl来回答)。但是,顺便说一句,许多人这样做是因为他们无法更改模式。社会启发法,比如适当地使用啤酒,有时会使这条道路变得平坦。让数据库人员信服的一点工作会在以后得到成倍的回报。另一方面,“完整堆栈开发人员”经常忽略数据库的任何复杂使用

    我不会让任何人深入阅读C.J.Date的数据库,但正确的模式有很大的价值。我的意思是,它在使用上花费的精力和复杂性最少。事情应该很简单,不必在应用程序级别重新安排这些事情

    您要计算每个答案被选择的次数。计数是数据库做得很好的事情,所以让数据库来做吧

    你有一些问题。问题有多种答案。调查将一系列问题组合在一起。人们对调查的反应是将答案与问题联系起来

    这里是一个简单的模式设计(一些数据库人员最终会出现并告诉我我做得不对,但这很好)。诀窍在于,任何东西都不必有多个未使用的列。所有东西都在一个整洁的小软件包中(“关系数据库”中的“关系”),它可以通过“外键”轻松地连接到其他东西(例如,问题id映射问题的答案)。例如,对于相同的
    问题id
    ,答案将有多行

    如果有人想用别致的建模工具来制作图片,那就去吧。我将此标记为社区维基

    Table: Questions
       id
       text
    
    Table: Answers
       id
       text
       question_id
    
    Table: Surveys
       id 
       title
    
    Table: SurveyQuestionSet
       id
       survey_id
       question_id   
    
    Table: Respondent
       id
       text
    
    Table: Response
       id
       respondent_id
       survey_id
       question_id
       answer_id
    
    一旦正确地进行了映射和规范化(请继续阅读),就可以很容易地通过选择获取所需的数据。规范化的理想就是不重复信息或让信息进入不一致的状态。在这些形式中,许多事情变得容易多了

    而且,如果你想实践这些东西,这个是一个现实生活中的数据集,标准化为我在这里介绍的内容


    现在,您只需计算调查和问题的特定组合出现的次数
    answer\u id
    。巧妙地使用
    groupby
    可以为您完成所有工作。您不再需要遍历各行,查看数十个未使用的列,试图找出如何对它们进行计数。不仅如此,您还可以进行这些操作,这意味着您只需编写一次查询,数据库就会假装其结果是一个表。然后,您可以简单地查询视图(这样所有的
    连接都被隐藏,同样也被隐藏),这非常简单。存储过程也经常被忽略。

    您需要将(糟糕的)数据模型转换为
    select questionNum ,question ,answer, count(*) as num_of
    from (
      select questionNum ,question ,answer1 as answer FROM results where answer1 IS NOT NULL union all
      select questionNum ,question ,answer2 as answer FROM results where answer2 IS NOT NULL  union all
      select questionNum ,question ,answer3 as answer FROM results where answer3 IS NOT NULL  union all
      select questionNum ,question ,answer4 as answer FROM results where answer4 IS NOT NULL  union all
      select questionNum ,question ,answer5 as answer FROM results where answer5 IS NOT NULL  union all
      select questionNum ,question ,answer6 as answer FROM results where answer6 IS NOT NULL  union all
      select questionNum ,question ,answer7 as answer FROM results where answer7 IS NOT NULL  union all
      select questionNum ,question ,answer8 as answer FROM results where answer8 IS NOT NULL  union all
      select questionNum ,question ,answer9 as answer FROM results where answer9 IS NOT NULL  union all
      select questionNum ,question ,answer10 as answer FROM results where answer10 IS NOT NULL
      ) as fiddle
    group by  questionNum ,question ,answer