Reputation: 327
I am new to MySQL.
I have a table with answer ids.
Answers can look like this:a1, a2, a3 ...
, but due to some problems some are NULL
, some are blank, and some are others like 1 a
etc.
Now I want to calculate the count of ids with a1 a2 a3
distinctly. But how is it possible to do this leaving others like NULL
, blanks and garbage.
The output should look like this
atype count
a1 45
a2 0
a3 56
If there is no row entry for a particular answer, the count should be 0.
Upvotes: 4
Views: 1749
Reputation: 8419
I have tried to present all major choices, each query is followed by demo link. Link contains description
select AType,count(*) as Count from tb2
where atype!='' and atype is not null and atype!='0' group by atype
Link1 (Best One) To count answers of each (existing) type other than balank 0 and null
select (select count(id) from tb2 where atype='a1') as A1,(select count(id) from
tb2 where atype='a2') as A2,(select count(id) from tb2 where atype='a3') as A3;
select AType,count(*) as Count from tb2
where atype in('a1','a2','a3') group by atype
Link3 count answers of types a1,a2 or a3 only.
First and last link do not take into account those types which are totally not present in the data. For example, If there is no answer with type a2 then first and third query would tell only number of answers with type a1 and a3 and will not mention answers of atype=a2. However 2nd query does.
Upvotes: 0
Reputation: 22604
You should use a table that contains your desired (correct) answer types:
| id | answer |
---------------
| 1 | a1 |
| 2 | a2 |
etc.
Then you can count the results that actually exist in your table:
SELECT atype, COUNT( * ) cnt FROM answers JOIN mytable
ON mytable.atype=answers.answer GROUP BY answers.answer;
(Replace mytable
with the appropriate table name).
Of course, this will only return existing results. To count the zero rows, you can look for answers that do not appear in your table:
SELECT answer, '0' AS cnt FROM answers WHERE answer NOT IN(
SELECT DISTINCT answer FROM answers JOIN mytable WHERE answer=mytable.atype );
Another way would be to use a counter table:
| id | answer | cnt |
---------------------
| 1 | a1 | 0 |
| 2 | a2 | 0 |
etc.
Then every time you want to count the results, do:
UPDATE answers SET cnt=0;
UPDATE answers SET cnt=
(SELECT cnt FROM
((SELECT answers.answer, COUNT(*) AS cnt
FROM answers JOIN mytable ON answers.answer=myTable.aType
GROUP BY answers.answer) AS tbl)
WHERE answers.answer=tbl.answer)
WHERE EXISTS
(SELECT cnt FROM
((SELECT answers.answer, COUNT(*) AS cnt
FROM answers JOIN mytable ON answers.answer=mytable.atype
GROUP BY answers.answer) AS tbl)
WHERE answers.answer=tbl.answer);
This will update the counter values in your answers table, and you can just SELECT * FROM answers ORDER BY answer
to get your result.
Be warned, though: I believe the second version, while convenient, will take a lot more computing power than the first one, due to all the subqueries needed.
Here is this example (UPDATE statements are on the left side!)
The best and least performance hungry solution for use cases like yours, in my opinion, is to create a counter table like the one I described in #2, but update the counter values at the time users are answering the questions, instead of re-calculating all the entries everytime you want to know the count.
This can easily be done. Everytime a question is answered correctly, increase the counter in the answers
table:
UPDATE answers SET cnt=cnt+1 WHERE answers.answer='a1';
And again, your query will be
SELECT * FROM answers ORDER BY answer;
Upvotes: 3
Reputation: 24046
select a.atype,count(*) as `Count`
from
(select 'a1' as atype union all
select 'a2' as atype union all
select 'a3' as atype )a
left join <your_table> b
on a.atype =b.atype
group by atype
Upvotes: 0