我正在编写一个人们提问的应用程序,并以调查的形式获得答案。每个问题都有2个选项,加上默认选项。当一个人回答问题时,他们可以选择提问者设定的2个选项,或者我选择的默认选项。例如,如果问题是香草与巧克力,选项将是香草,巧克力和两者。我希望能够将为问题选择的选项百分比制成表格,即25%说巧克力,30%说香草,45%不说。
我将首先显示表结构和我正在运行的查询。
这些是涉及的表(注意:这些不是完整的表结构):
--questions--
id
user_id
topic
description
--options--
id
text
default (bool)
--questions_options--
question_id
option_id
--answers--
id
question_id
user_id
option_id
以下是查询:
SELECT
options.id AS option_id, options.text, options.default,
ROUND(
IFNULL(
(COUNT(answers.option_id) * 100)
/
(SELECT COUNT(answers.option_id) FROM answers WHERE question_id = QUESTION_ID)
, 0)
, 2) AS percentage
FROM options
LEFT JOIN questions_options ON questions_options.option_id = options.id
LEFT JOIN answers ON answers.option_id = options.id
WHERE questions_options.question_id = QUESTION_ID
OR options.default = '1'
GROUP BY options.id
ORDER BY percentage DESC, option_id ASC
其中QUESTION_ID是整数常量。
问题是查询不仅仅限制针对特定问题的答案的答案,而且由于选项有很多问题,我得到的结果如600% for vanilla
(如果多个问题使用香草作为选项)。如果选项对于一个问题是唯一的,那么百分比是有意义的,除了默认选项,所有问题都存在。我尝试将WHERE answers.question_id = QUESTION_ID
放在那里,但它没有用。
任何解决方案?
由于
答案 0 :(得分:0)
我可以看到的问题:
您GROUP BY
options.id
表示您获得了options.text
和options.default
的随机值。这可能会也可能不会改变您的结果,具体取决于您的数据结构。如果每id
行有多行,则数据不准确或会产生误导。
您的除数有WHERE
条款,但百分比计算中没有您的红利 - 这意味着您的红利数量永远不会更低。尝试将WHERE question_id = QUESTION_ID
放入第一个COUNT
语句。
答案 1 :(得分:0)
你正在以错误的方向进行连接 - 你首先要查看选项,即使你已经明确表示你想要用问题列表的东西。这意味着您将获得所有选项的结果,无论它们是否与您的问题相关......
哦,我假设answer_id
已映射到question_id
,或者您无法获得任何有意义的结果(也就是说 - 答案不是否则映射到问题...)
请尝试此查询:
SELECT b.id, b.text, b.default, (SELECT IFNULL(
ROUND((COUNT(c.id) * 100) /
(SELECT COUNT(d.id)
FROM answers as d
WHERE d.answer_id = a.question_id)
, 2)
, 0)
FROM answers as c
WHERE c.answer_id = a.question_id
AND c.option_id = a.option_id) as percentage
FROM questions_options as a
JOIN options as b
ON b.id = a.option_id
WHERE a.question_id = QUESTION_ID
ORDER BY percentage DESC, a.option_id ASC
请注意,我没有MySQL的副本来执行此操作,我通常会使用CTE(我已被告知MySQL不支持)。
<小时/> 编辑:
鉴于“默认”选项可能无法通过questions_options
表进行映射,请尝试以下操作:
SELECT a.id, a.text, a.default, IFNULL(
ROUND((b.answerCount * 100) /
(SELECT COUNT(c.id)
FROM answers as c
WHERE c.answer_id = QUESTION_ID)
, 2)
, 0)
FROM options as a
LEFT JOIN (SELECT c.option_id, count(c.id) as answerCount
FROM answers as c
WHERE c.question_id = QUESTION_ID
GROUP BY c.option_id) as b
ON b.option_id = a.id
请注意,对于调查受访者不的每个“默认”答案,您仍然会得到“毫无意义”的“0”结果 - 并且无法将这些与任何实际区别开来'0'会显示 向受访者提供的“默认”答案的结果。您可能远更好地在questions_options
表中放置所谓的“默认”选项 - 实际上,您无法确定所有提交给受访者的选项(您可以回答哪些选项,这是完全不同的);对您的公司而言,这可能是一个巨大的业务责任问题。此外,一些“默认”选项在上下文中可能没有意义 - “你喜欢你的茶还是冷的”,“是的”。