2013-04-18 50 views
2

我是PHP和MySQL的新手,并且正在为此苦苦挣扎...我正在从PHP插入页面收集表单数据。这是一份调查问卷。有20个问题,所有答案将是ABC。该表有一个id列和每个问题的列(Q1, Q2, Q3... Q20)。数据可能看起来像这样;现在如何计算单行的字段值?

+------+-----+ 
| id | 1 | 
+------+-----+ 
| Q1 | A | 
| Q2 | B | 
| Q3 | A | 
| . | . | 
| . | . | 
| . | . | 
| Q20 | C | 
+------+-----+ 

,我所要做的是计算ABC多少值出现在单行(与id=1为例)。

我发现了很多方法来计算多列中的值,但到目前为止还没有找到一种方法来统计/分组单个行中的值。

回答

0

这里是你如何可以与一个MySQL查询做到这一点:

select id, 
    sum(case when `1` = 'A' then 1 else 0 end) as CountA, 
    sum(case when `1` = 'B' then 1 else 0 end) as CountB, 
    sum(case when `1` = 'C' then 1 else 0 end) as CountC 
from SurveyTable 
group by id 
order by id; 

这里有一个SQL Fiddle有限的测试数据。


附录。卡洛斯发布了一个更新的结构,导致以下答案。希望这些都是接近:)

这会给你一个很宽行总计:

select 
    sum(case when Q1 = 'A' then 1 else 0 end) as Q1CountA, 
    sum(case when Q1 = 'B' then 1 else 0 end) as Q1CountB, 
    sum(case when Q1 = 'C' then 1 else 0 end) as Q1CountC, 
    sum(case when Q2 = 'A' then 1 else 0 end) as Q2CountA, 
    sum(case when Q2 = 'B' then 1 else 0 end) as Q2CountB, 
    sum(case when Q2 = 'C' then 1 else 0 end) as Q2CountC, 
    sum(case when Q3 = 'A' then 1 else 0 end) as Q3CountA, 
    sum(case when Q3 = 'B' then 1 else 0 end) as Q3CountB, 
    sum(case when Q3 = 'C' then 1 else 0 end) as Q3CountC, 
    sum(case when Q4 = 'A' then 1 else 0 end) as Q4CountA, 
    sum(case when Q4 = 'B' then 1 else 0 end) as Q4CountB, 
    sum(case when Q4 = 'C' then 1 else 0 end) as Q4CountC, 
    sum(case when Q5 = 'A' then 1 else 0 end) as Q5CountA, 
    sum(case when Q5 = 'B' then 1 else 0 end) as Q5CountB, 
    sum(case when Q5 = 'C' then 1 else 0 end) as Q5CountC 
from SurveyTable; 

如果你想获得每个问题一列,然后试试这个:

select 
    QuestionID, 
    sum(case when Answer = 'A' then 1 else 0 end) as CountA, 
    sum(case when Answer = 'B' then 1 else 0 end) as CountB, 
    sum(case when Answer = 'C' then 1 else 0 end) as CountC 
from (
    select 'Question1' as QuestionID, Q1 as Answer from surveytable 
    union all select 'Question2', Q2 from surveytable 
    union all select 'Question3', Q3 from surveytable 
    union all select 'Question4', Q4 from surveytable 
    union all select 'Question5', Q5 from surveytable) x 
group by QuestionID 

有小提琴here


另附录:计数需要通过ID,因为有一个ID每行有没有必要为SUM

这改变了方法。它首先将答案串在一起:

concat(q1,q2,q3,q4,q5) -- result for ID=1 in the test data: 'ABCAC' 

...然后它吸收从字符串的每A发生:

replace(concat(q1,q2,q3,q4,q5), 'A', '') -- result for ID=1: 'BCC' 

...第一串(ABCAC)的长度5,并且所述第二串(BCC)是长度3的长度差是数A答案:2。这就好像我可以解释这一点。现在查询:

select 
    id, 
    5 - length(replace(concat(q1,q2,q3,q4,q5), 'A', '')) AS CountA, 
    5 - length(replace(concat(q1,q2,q3,q4,q5), 'B', '')) AS CountB, 
    5 - length(replace(concat(q1,q2,q3,q4,q5), 'C', '')) AS CountC 
from surveytable; 

更新的小提琴是here

这只给出原始数据。格式化会有点棘手,但它不应该太糟糕,特别是如果你用前端语言来做。如果必须使用MySQL对于这一点,它可能会更容易把上面为子查询和外部查询应用的格式:

select 
    id, 
    CONCAT('You have chosen ' ...and miles of formatting logic using CountA, etc) 
from (
    select 
    id, 
    5 - length(replace(concat(q1,q2,q3,q4,q5), 'A', '')) AS CountA, 
    5 - length(replace(concat(q1,q2,q3,q4,q5), 'B', '')) AS CountB, 
    5 - length(replace(concat(q1,q2,q3,q4,q5), 'C', '')) AS CountC 
    from surveytable) x 
+0

谢谢埃德,这看起来很有趣,但我的表格结构实际上更像这样;创建表surveytable(id int,'Q1' char(1),'Q2' char(1),'Q3' char(1),'Q4' char(1),'Q5' char(1)); (1,“A”,“B”,“C”,“A”,“C”), (2,'A','A','A','B' ,'C'), (3,'B','B','A','C','C'); – Carlos

+0

@卡洛斯 - 你的表格结构与你的评论截然分开。对不起 - 忽略 - 我现在看到它。我马上更新我的答案。 –

+0

是的,对不起,我是新来的stackoverflow,还没有格式化的悬念。 – Carlos

0

在PHP中,你可以在查询的结果加载到arary,然后用array_count_values让每个答案的计数:

$array = array(); 

while ($row = $result->fetch_assoc()) { 
    $array[] = $row; 
} 

// print_r(array_count_values($array); 

foreach(array_count_values($array) as $key => $value) 
{ 
    echo 'Answer ' . $key . ' was chosen ' . $value . ' times <br>'; 
} 

Working Fiddle

+0

嗨埃文,我会如何馅记录的值(一个完整的行)到数组中? – Carlos

+0

@Carlos你使用'while循环'做了这个,如上所示。如果这没有意义,我可以尝试使它更清楚,但是你注意到了那部分? –

+0

啊,不,我没有注意到,我正在看小提琴上的代码......你可以为我扩展它(我习惯于ASP,并且是PHP的新手!) – Carlos

0

免责声明:从内存中,因此可以不确切的工作。

这个怎么样?

SELECT 1 AS 1, (SELECT COUNT(1)FROM问题WHERE 1 = 'A')AS A, (SELECT COUNT(1)FROM问题WHERE 1 = 'B')AS B, (SELECT COUNT(1)FROM WHERE 1 ='C')AS C

希望这会有所帮助。