简体   繁体   English

如何计算单行中的字段值?

[英]How do I Count Field Values from a Single Row?

I'm new to PHP and MySQL and am struggling with this... I am collecting form data from a PHP insert page. 我是PHP和MySQL的新手,正在为此而苦苦挣扎...我正在从PHP插入页面收集表单数据。 It is a survey questionnaire. 这是一个调查问卷。 There are 20 questions, and all the answers will either be A , B and C . 有20个问题,所有答案将为ABC The table has an id column, and a column for each question ( Q1, Q2, Q3... Q20 ). 该表具有一个id列,以及每个问题( Q1, Q2, Q3... Q20 )的列。 The data may look something like this; 数据可能看起来像这样。

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

Now, what I am trying to do is to count how many values of A , B and C appear in a single row (with id=1 for example). 现在,我想做的是计算ABC多少个值出现在一行中(例如, id=1 )。

I've found lots of ways of counting values in multiple columns, but so far have not found a way to count/group values in a single row. 我发现了很多方法可以对多列中的值进行计数,但是到目前为止,还没有找到一种方法来对单行中的值进行计数/分组。

In PHP, you could load the results of the query into an arary, and then use array_count_values to get the count of each answer: 在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 工作小提琴

DISCLAIMER: from memory so may not exactly work. 免责声明:来自内存,因此可能无法完全正常工作。

How about this? 这个怎么样?

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

Hope this helps. 希望这可以帮助。

Here's how you can do it with a MySQL query: 使用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;

Here's a SQL Fiddle with limited test data. 这是带有有限测试数据的SQL Fiddle


Addendum . 附录 Carlos posted an updated structure, leading to the following answers. 卡洛斯(Carlos)发布了更新的结构,得出以下答案。 Hope these are close :) 希望这些都近:)

This will give you one very wide row with grand totals: 这将为您提供总计很大的一排:

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;

If you want to get one row per question then try this: 如果您想每个问题获得一行,请尝试以下操作:

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

There's a Fiddle here . 有一个小提琴在这里


Another Addendum : Counts needed by ID , and because there's one ID per row there's no need for SUM . 另一个附录ID所需的计数,并且由于每行有一个ID ,因此不需要SUM

This changes the approach. 这改变了方法。 It first strings the answers together: 首先将答案串在一起:

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

... then it sucks every occurrence of A from the string: ...然后从字符串中吸收每次出现的A

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

... the first string ( ABCAC ) is length 5 , and the second string ( BCC ) is length 3. The difference in length is the number of A answers: 2 . ...第一个字符串( ABCAC )的长度为5 ,第二个字符串( BCC )的长度为3。长度的差是A答案的数量: 2 That's about as well as I can explain this. 差不多可以解释了。 Now for the query: 现在进行查询:

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;

The updated Fiddle is here . 更新的小提琴在这里

This gives the raw data only. 这仅提供原始数据。 The formatting will be a bit tricky but it shouldn't be too bad, especially if you do it with a front-end language. 格式会有些棘手,但应该不会太糟,特别是如果使用前端语言。 If you must use MySQL for this, it will probably be easier to put the above into a subquery and apply the formatting in the outer query: 如果必须为此使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM