我有一个民意调查系统。我使用此查询来计算每个问题的答案。如何获得每个回答选项的百分比如下:
question 1 ---> option1=20.13 % ---> option2=79.87 %
question 2 ---> option3=100 %
question 3 ---> option4=30 % ---> option5=70 %
....
我尝试了这个查询但不是我的愿望:
[getPollResult]
@poll_form_id int
AS
BEGIN
SELECT a.question_id,a.title,COUNT(*) vote
FROM tbl_poll_option a
JOIN tbl_poll_answer b ON a.Id=b.option_id
JOIN tbl_poll_question c ON a.question_id=c.Id
WHERE poll_form_id=@poll_form_id
GROUP BY a.title,a.question_id
END
答案 0 :(得分:3)
我同意在前端进行计算(如百分比)的建议。
话虽如此,这可能对您有所帮助。
设计限制:这适用于相对较小的数据集,我发现" with()"语法比制作临时表更容易使用,希望我记得清理它们。 (更多关于"与......作为......" sytnax see here)。
以下sql(未经测试)尝试生成两个临时结果集。
counts_by_option - # of votes for each question+option pair
counts_by_question - total # of votes for each question
让我们轻松一点:
这或多或少是你的开始(实际上更多一点,我想我们以后可能想知道问题和选项,所以我们现在就抓住它们):
with counts_by_option( question_id, question_title, option_id, option_title, vote_cnt )
as (
SELECT opt.question_id
, quest.title as question_title
, opt.id as option_id
, opt.title as option_title
, COUNT(*) vote_cnt
FROM tbl_poll_option opt
JOIN tbl_poll_answer ans ON ans.option_id = opt.Id
JOIN tbl_poll_question quest ON quest.Id = opt.question_id
WHERE poll_form_id=@poll_form_id
GROUP BY opt.question_id, quest.title, opt.id, opt.title
)
select * from counts_by_option
order by question_id, option_id
如果可以的话,让我们扩展sql并添加我们的下一个临时结果集......
现在我们可以使用我们的选项总数来生成每个问题的总票数;我们需要一点来计算实际的%ge。
with counts_by_option( question_id, question_title, option_id, option_title, vote_cnt )
as (
SELECT opt.question_id
, quest.title as question_title
, opt.id as option_id
, opt.title as option_title
, COUNT(*) vote_cnt
FROM tbl_poll_option opt
JOIN tbl_poll_answer ans ON ans.option_id = opt.Id
JOIN tbl_poll_question quest ON quest.Id = opt.question_id
WHERE poll_form_id=@poll_form_id
GROUP BY opt.question_id, quest.title, opt.id, opt.title
)
-- select * from counts_by_option order by question_id, option_id
-- (I like to comment out select but leave in place for future testing...)
, counts_by_question( question_id, question_total_votes )
as (
select question_id, sum(vote_cnt) as question_total_votes
from counts_by_option group by question_id
)
select * from counts_by_question order by question_id
如果有效,我们(最终)能够回答有关百分比的原始问题:
with counts_by_option( question_id, question_title, option_id, option_title, vote_cnt )
as (
SELECT opt.question_id
, quest.title as question_title
, opt.id as option_id
, opt.title as option_title
, COUNT(*) vote_cnt
FROM tbl_poll_option opt
JOIN tbl_poll_answer ans ON ans.option_id = opt.Id
JOIN tbl_poll_question quest ON quest.Id = opt.question_id
WHERE poll_form_id=@poll_form_id
GROUP BY opt.question_id, quest.title, opt.id, opt.title
)
-- select * from counts_by_option order by question_id, option_id
-- (I like to comment out select but leave in place for future testing...)
, counts_by_question( question_id, question_total_votes )
as (
select question_id, sum(vote_cnt) as question_total_votes
from counts_by_option group by question_id
)
-- select * from counts_by_question order by question_id
select question_id
, question_title
, option_id
, option_title
, vote_cnt
, (100.0 * vote_cnt)
/ (select b.question_total_votes
from counts_by_question b
where b.question_id = a.question_id
) as option_percentage
from counts_by_option a
order by question_id, vote_cnt desc
结果集由 counts_by_option a 驱动。
百分比表达式要求 counts_by_question b 寻求帮助。
让我们关注 option_percentage 的表达式:
(100.0 * vote_cnt)
/ (select b.question_total_votes
from counts_by_question b
where b.question_id = a.question_id
)
as option_percentage
这有点复杂(这就是为什么我更喜欢做前端聚合这样的事情)但不是太糟糕......
我们首先将 vote_count 乘以 100.0 。
然后我们使用当前的OPTION驱动一个命中question_total_values的子查询来查找我们当前问题的总投票数。
注意限定词 a 和 b 这些对于 count_by_question 仅对 a 重点关注我们的子查询非常重要使用这个where子句的当前问题:其中b.question_id = a.question_id (很重要,因为像这样的子查询只能返回一个值,否则它会在执行时出错)。
如果任何问题的总票数为零(例如除以零错误),这将会爆炸。
编辑:构建 counts_by_option 的方式,只会使用带答案的问题(表 tbl_poll_answer ),因此 counts_by_question中的所有值将为非零。
答案 1 :(得分:1)
上述案例的架构
CREATE TABLE #POLL_QUESTION (QUESTION_ID INT, QUESTION VARCHAR(50))
INSERT INTO #POLL_QUESTION
SELECT 1,'WHAT?'
UNION ALL
SELECT 2,'WHEN?'
UNION ALL
SELECT 3,'WHY?'
UNION ALL
SELECT 4,'WHERE?'
CREATE TABLE #POLL_OPTION(OPTION_ID INT , QUESTION_ID INT, OPTION_NME VARCHAR(50))
INSERT INTO #POLL_OPTION
SELECT 1,1,'A'
UNION ALL
SELECT 2,1,'B'
UNION ALL
SELECT 3,1,'C'
UNION ALL
SELECT 4,2,'A'
UNION ALL
SELECT 5,2,'B'
UNION ALL
SELECT 6,2,'C'
UNION ALL
SELECT 7,3,'A'
UNION ALL
SELECT 8,3,'B'
UNION ALL
SELECT 9,3,'C'
UNION ALL
SELECT 10,4,'A'
UNION ALL
SELECT 11,4,'B'
UNION ALL
SELECT 12,4,'C'
CREATE TABLE #POLL_ANSWER(ANSWER_ID INT, OPTION_ID INT)
INSERT INTO #POLL_ANSWER
SELECT 1,2
UNION ALL
SELECT 2,2
UNION ALL
SELECT 3,3
UNION ALL
SELECT 4,4
UNION ALL
SELECT 5,4
UNION ALL
SELECT 6,4
UNION ALL
SELECT 7,5
UNION ALL
SELECT 8,7
UNION ALL
SELECT 9,8
UNION ALL
SELECT 10,9
UNION ALL
SELECT 11,10
UNION ALL
SELECT 12,10
数据的统计
SELECT Q.QUESTION_ID,Q.QUESTION,O.OPTION_NME,COUNT(O.OPTION_NME)COUNT_OPTION,LEFTQUERY.COUNT_QUESTION, (COUNT(O.OPTION_NME)*100)/LEFTQUERY.COUNT_QUESTION AS PER FROM #POLL_QUESTION Q
INNER JOIN #POLL_OPTION O ON Q.QUESTION_ID=O.QUESTION_ID
INNER JOIN #POLL_ANSWER A ON O.OPTION_ID= A.OPTION_ID
LEFT JOIN
(
SELECT Q.QUESTION_ID,Q.QUESTION, COUNt(O.OPTION_NME)COUNT_QUESTION FROM #POLL_QUESTION Q
INNER JOIN #POLL_OPTION O ON Q.QUESTION_ID=O.QUESTION_ID
INNER JOIN #POLL_ANSWER A ON O.OPTION_ID= A.OPTION_ID
GROUP BY Q.QUESTION_ID,Q.QUESTION
)AS LEFTQUERY ON Q.QUESTION_ID= LEFTQUERY.QUESTION_ID
GROUP BY Q.QUESTION_ID,Q.QUESTION,O.OPTION_NME,
LEFTQUERY.COUNT_QUESTION
答案 2 :(得分:1)
select
q.title,
o.title,
CAST(count(distinct o.id) as float)
/ (SELECT count(allo.id)
FROM option allo
WHERE q.option_FK = allo.id)
* 100.0,
FROM question q
inner join option o on q.option_FK = o.id
GROUP BY q.id, q.title, q.option_FK, o.id, o.title
(可能需要围绕演员进行一些清理)。
将返回此列表:
question 1, option1, 20.13
question 1, option2, 79.87
question 2, option3, 100
question 3, option4, 30
question 3, option5, 70
理想情况下,它可以用更高级的编程语言进行进一步处理。