SQL counting by groups - mysql

I have a table that looks like this
id name answer question
1 john correct 1
1 john correct 2
1 john correct 3
1 john wrong 4
2 lee wrong 1
2 lee correct 2
2 lee correct 3
3 ana correct 1
3 ana wrong 2
I want to be able to get a list of all unique users, and see how many questions they have correct and how many are wrong.
I tried something like this but I cant seem to make it work:
SELECT id, user_id, name, question_id, (select count(answer) from table where answer = 'CORRECT') as correct, (select count(answer) from table where answer= 'WRONG') as wrong FROM table GROUP BY user_id
Can someone help me get me on the right track? thanks

Try this:
SELECT name, answer, COUNT(*) FROM yourtablenamehere GROUP BY name, answer

You do what you want with conditional sums:
select name, sum(case when answer = 'correct' then 1 else 0 end) as correct,
sum(case when answer = 'wrong' then 1 else 0 end) as wrong
from table t
group by name

for MySQL it could be like this:
SELECT user_id, name,SUM(IF(answer='correct',1,0)) AS correct,SUM(IF(answer='wrong',1,0)) as wrong FROM table GROUP BY user_id

Related

mysql sorting data in two levels possible?

Iam trying to analyze some date from a mysql table.
The data is a representation of incomming calls, each line represents one call
category purpose
cars question
bikes question
cars question
cars complaints
scooters question
bikes complaints
now for the plotting I need the data to look like this
category cat_count question complaints
cars 3 2 1
bikes 2 1 1
scooters 1 1
I figured out that I can sort and count by one field by using something like this
SELECT category, count(*) FROM stat GROUP BY category ORDER BY count(*) desc;
which will give me
category count
cars 3
bikes 2
scooters 1
but how can I add the purpose counts to that output?
I would usually write a php or bash script, but if its possible to do it in mysql I would rather do it like that instead of having a 3 loop script noone will understand in 1 year :-))
Thanks in advance for any hint (even if the hint is "impossible")
You can do this way:
SELECT category, count(*) as cat_count,
SUM(CASE WHEN purpose='question' THEN 1 ELSE 0 END) as question,
SUM(CASE WHEN purpose='complaints' THEN 1 ELSE 0 END) as complaints
FROM stat
GROUP BY category
ORDER BY count(*) desc;
Result:
CATEGORY CAT_COUNT QUESTION COMPLAINTS
cars 3 2 1
bikes 2 1 1
scooters 1 1 0
See result in SQL Fiddle.

mysql - ignore other records if a condition is met

Trying to work out how best to phrase this questions, but best done by example I think.
I have the following output from a query
league_id user_id outcome_id
5 1 1
5 1 4
5 2 1
As you can see there are two different outcome values.
It is valid that there would be more than one case of league_id and user_id being the same… eg in the example above 5 and 1.
What I'd like is to produce summary data whereby if a combination of league_id and user_id has an outcome of '4' then there would be output of 'FAIL' and all the outcomes of '1' are ignored for that league_id and user_id combinations. If there is no presence of a '4' then the summary would output pass.
It would result in something like below…
league_id user_id outcome_id
5 1 FAIL
5 2 PASS
Sorry to say I'm stumped how I would achieve this! Can someone help please?
Thanks.
DS
SELECT league_id,user_id,
CASE WHEN outcome=0 THEN 'PASS' ELSE 'FAIL' END as outcome_id
FROM
(
SELECT league_id,user_id,SUM(CASE WHEN outcome_id=4 THEN 1 ELSE 0 END) as outcome
FROM tableName
GROUP BY league_id,user_id
) As Z

Selecting id and value where max occurs

I've solved one issue and ran into another. Basicaly i want to select question_id, answer and maximum number of occurences. I run my query from basic table that gathers questions and answers to them (question id represents question and answer represents answer from 0 to 5 that corresponds to other table but that doesn't matter).
**survey_result**
question_id
answer (int from 0 to 5)
Sample survey_result:
question_id answer
1 3
1 5
1 2
2 2
2 0
2 4
Here's the query, it's purpose is to check for every single question, which answer (from 0 to 5) occured the most.
select question_id, answer, max(occurence_number) FROM
(select question_id, answer, count(*) as occurence_number
from survey_result
group by question_id, answer
order by question_id asc, occurence_number desc) as results
GROUP BY question_id
So a sub query results in something like this:
question_id answer occurence_number
1 0 12
1 1 20
1 2 34
1 3 5
1 4 9
1 5 15
But main query results something like this:
question_id answer occurence_number
1 0 12
2 0 20
3 0 34
4 0 5
So the problem is that it always shows answer 0, and i want to get correct answer number.
Sadly a bit redundant due to MySQL's lack of a WITH statement, but this should do what you want. In case of a tie, it will return the higher answer.
SELECT s1.question_id, MAX(s1.answer) answer, MAX(s1.c) occurrences
FROM
(SELECT question_id, answer, COUNT(*) c
FROM survey_result GROUP BY question_id,answer) s1
LEFT JOIN
(SELECT question_id, answer, COUNT(*) c
FROM survey_result GROUP BY question_id,answer) s2
ON s1.question_id=s2.question_id
AND s1.c < s2.c
WHERE s2.c IS NULL
GROUP BY question_id
An SQLfiddle to play with.
I think you are overcomplicating it, try this:
select question_id, answer, count(*) as occurence_number
from survey_result
group by question_id, answer

Limit similar ids - results into sql

2i've a table of repeated items, i got this table done from a left join.-
Lets say that this table alias is "piked"
ID Product PickedBY
1 Basket Josh
1 Basket Jessica
1 Basket Josh
1 Basket Mike
1 Basket Mike
2 Seat Alan
3 Computer Jessica
4 Mouse Josh
4 Mouse Mike
4 Mouse Jessica
I wish to limit the equal Ids to 2. how do i do it? so, if i list just ids result will look 1,1,2,3,4,4.
Thanks
Your question doesn't make sense to me which makes me wonder what you want to achieve with such a query but you can try to group the results:
select id, count(*)
from piked
group by id
That's not exactly what you asked but you can tell whether an id has duplicates by looking at the second column of the result. The result will be
1,5
2,1
3,1
4,3
This should do the trick:
SELECT ID, Product, PickedBy FROM (
SELECT
IF(#prev != q.ID, #rownum:=1, #rownum:=#rownum+1) as rownumber, #prev:=q.ID, q.*
FROM (
SELECT
ID, Product, PickedBy
FROM piked
, (SELECT #rownum:=0, #prev:=0) r
ORDER BY ID
)q
)asdf
WHERE asdf.rownumber <= 2

Mysql multiple distinct wont work

I have tried this multiple distinct from MySQL and I cant seem to get anything to work... I have a table that is a history table. The appartments can be found many times from the same building with different status. I need to find the newest one for each appartment (the one with the highest id ORDER BY id)
id building appartment_id status
208 1 2 2
209 1 3 2
210 1 4 2
211 1 5 2
212 1 6 2
213 1 7 2
214 1 2 1
215 1 2 3
But how do I do that?! :S
I have tried this:
SELECT *, GROUP_CONCAT(appartment_id, building)
FROM `ib30_history`
group by appartment_id, building
order by id DESC
It seems to work but im not sure that is the right way of doing it and the code that uses the output seems to make funny things running through the data so im not sure it really works!
SELECT yourtable.id, yourtable.building, yourtable.appartment_id, yourtable.status
FROM yourtable
INNER JOIN (
SELECT MAX(id) AS id
FROM yourtable
GROUP BY building, appartment_id
) AS child ON yourtable.id = child.id
Get rid of distinct and use something like:
GROUP BY building , appartment_id
What you're looking for is called GROUP BY, and MySQL's documentation knows a lot about how it's to be used. At the timeI type this, the OP doesn't contain a query so I cannot give you an example...
SELECT a.*
FROM table_name a
INNER JOIN
(SELECT MAX(id) as max_id
FROM table_name
GROUP BY appartment_id) b
ON (b.max_id = a.id)