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

发布于 2024-12-18 17:50:22 字数 1236 浏览 1 评论 0原文

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

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

如何获得“选择四”?这样我就可以正确显示所有调查结果,包括没有人投票的选项。我也尝试过使用 OUTER JOIN,但没有成功。

我很羞愧,因为这可能听起来是一个愚蠢的问题,但我在数据库和关系方面还有很多东西需要学习

I'm struggling with a task that could be very simple but I'm having a hard time figuring it out. I've two database table:

options_table

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

and 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     |

From this example, we have 2 votes on option 1, 3 votes on option 2 and 1 vote on option 3, but none on option 4.
I'd like to retrieve all the options name with the relative count, but I can't get the option without votes. I'm sure I'm overlooking something, it's workday's end and I must be tired.
I tried something like:

   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

but I just get

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

How do I get also "opt four"? So I can properly display all the survey results including the option noone voted. I also tried using OUTER JOINs, but to no avail.

I'm ashamed for this might sound a stupid question, but I still have a lot to learn on databases and relationships

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

合久必婚 2024-12-25 17:50:22

使用 LEFT 而不是 INNER 连接 - 将包含所有选项的表放在左侧,将缺少选项的表放在右侧。

将使用右表中的列的任何条件(例如 v.survey_id = 1 条件)从 WHERE 移至 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,则每个选项的查询都会对使用此选项投票的所有问题进行计票。

Use LEFT instead of INNER join - put in the Left side the table with all the options, and in the Right side the table with missing options.

Move any condition that uses a column from the Right table, like the v.survey_id = 1 one, from the WHERE to the ON clause.

Use COUNT(RightTable.column) instead of COUNT(*), so you get 0 for options not voted:

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

I suppose that (option_id, question_id) is the Primary (or a Unique) Key of the options table. That's why you either need to GROUP BY both of them or WHERE o.question_id and GROUP BY o.option_id.

Otherwise, if you only GROUP BY o.option_id, the query for every option, will count votes for all questions that were voted with this option.

泛泛之交 2024-12-25 17:50:22
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;
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;
烟雨扶苏 2024-12-25 17:50:22

您可以使用 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;

Instead of using INNER JOIN (JOIN), you can use LEFT JOIN to achieve this

 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;
转身泪倾城 2024-12-25 17:50:22

尝试一下

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,您只会获得两个表中都有相应项目的记录。

Try this

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

If you use INNER JOIN you only get records having a corresponding item in both tables.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文