从调查表中选择并统计投票,其中并非所有选项都有投票

时间:2011-11-29 16:57:31

标签: mysql join rdbms one-to-many

我正在努力完成一项非常简单的任务,但我很难搞清楚。我有两个数据库表:

options_table

option_id | option_name | question_id |
    1     |   opt one   |      4      |
    2     |   opt two   |      4      |
    3     |   opt three |      4      |
    4     |   opt four  |      4      |

和votes_table

question_id | survey_id | option_id |
    4       |    1      |     1     |
    4       |    1      |     2     |
    4       |    1      |     2     |
    4       |    1      |     1     |
    4       |    1      |     3     |
    4       |    1      |     2     |

从这个例子中,我们对选项1有2票,对选项2有3票,对选项3有1票,但在选项4上没有。 我想用相对计数检索所有选项名称,但是如果没有投票,我就无法获得选项。我确定我忽视了一些事情,这是工作日的结束,我一定很累。 我试过像:

   SELECT o.option_name, count(*) as cnt 
   FROM votes_table AS v 
   JOIN options_table AS o 
   ON o.option_id = v.option_id 
   WHERE v.survey_id = 1 
   GROUP BY o.option_name

但我得到了

option_name | option_id | cnt
 opt one    |   1       |  2
 opt two    |   2       |  3
 opt three  |   3       |  1

我如何获得“opt four”?所以我可以正确显示所有的调查结果,包括没有投票的选项。我也试过使用OUTER JOIN,但无济于事。

我为此感到羞耻可能听起来是一个愚蠢的问题,但我仍然需要学习很多关于数据库和关系的知识

4 个答案:

答案 0 :(得分:1)

SELECT 
  o.option_name, 
  ( SELECT 
      count(*) 
    FROM 
      votes_table 
    WHERE  
      v.survey_id = 1
    AND
      v.question_id = o.question_id
    AND
      v.otion_id = o.option_id 
  ) as cnt 
options_table AS o;

答案 1 :(得分:1)

使用LEFT而不是INNER加入 - 在表格的左侧放置所有选项,在右侧放置缺少选项的表格。

v.survey_id = 1WHERE子句移动使用右表中的列的任何条件,例如ON列。

使用COUNT(RightTable.column)代替COUNT(*),因此您可以获得0未投票的选项:

SELECT o.question_id
     , o.option_name
     , COUNT(v.option_id) as cnt 
FROM 
    options_table AS o  
  LEFT JOIN 
    votes_table AS v
      ON  v.option_id = o.option_id 
      AND v.question_id = o.question_id
      AND v.survey_id = 1 
WHERE o.question_id = 4            --- if you want results for one question only 
GROUP BY o.question_id
       , o.option_id

我认为(option_id, question_id)options表的主要(或唯一)键。这就是为什么你需要GROUP BY这两者或WHERE o.question_idGROUP BY o.option_id

否则,如果您只有GROUP BY o.option_id,则对每个选项的查询将计算对使用此选项投票的所有问题的投票。

答案 2 :(得分:0)

您可以使用LEFT JOIN来实现此

,而不是使用INNER JOIN(JOIN)
 SELECT o.option_name, count(*) as cnt 
 FROM options_table AS o  
 LEFT JOIN votes_table AS v
 ON o.option_id = v.option_id 
 WHERE v.survey_id = 1 
 GROUP BY o.option_name;

答案 3 :(得分:0)

试试这个

SELECT o.option_name, count(*) AS cnt 
FROM options_table o 
LEFT JOIN votes_table v ON o.option_id = v.option_id 
WHERE v.survey_id = 1 
GROUP BY o.option_name

如果使用INNER JOIN,则只能获得两个表中都有相应项的记录。