MySQL query: select how many times was every option selected - mysql

I have 2 mysql tables
1. questions: with the following columns: id, title, answer1, answer2, answer3, answer4, answer5, nranswers.
and
2. answers with the following columns: id, questionid, userid, answer
Every question has maximum 5 answers( it can have between 2 and 5 answers). My problem is that I want to select from my database, for a given question, how many times was every option selected.
For example, let's suppose I have the question with the id 46, with 4 answers, and 48 users voted for the option #2, 37 users for the option #1 and 39 for the option #4.
I want a query that selects that and write these things:
1 37
2 48
3 0
4 39
P.S. VERY IMPORTANT! IT MUST COUNT ONLY NRANSWERS ANSWERS, AND IT MUST ECHO THE ONES THAT WEREN'T VOTED BEFORE.

Best way to do this: change table defs:
Questions (Question_ID, title)
Answers (Answer_ID, Question_ID, answer_text)
Votes (User_ID, Answer_ID)
Which contains the same data as your def, but is in first normal form. Selecting the counts is now really easy
SELECT
a.Answer_ID,
COUNT(v.User_ID)
FROM
Questions q
LEFT JOIN Answers a ON q.Question_ID = a.Question_ID
LEFT JOIN Votes v ON a.Answer_ID = v.Answer_ID
WHERE q.Question_ID = 46 -- or any other question ID
GROUP BY a.Answer_ID
ORDER BY a.Answer_ID;

SELECT q.id as question, a.answer as answer, count(a.answer) as count FROM questions q, answers a Group by q.id,a.answer
Problem with above that it will return as follows
question answer Count
1 1 37
1 2 48
1 4 39
1 3 0 this is missing
OR
SELECT a.question_id, a.answer, count(a.answer) FROM test.answers a Group by a.question_id, a.answer

Related

sql select with count condition

I have 2 tables in my DB, first table called "questions" and hold questions with id, second table called "answers" and hold answers for the questions (as multiple choices).
how to select questions that have less than 4 answers?
questions table:
id question
1 what is ...?
2 how many ...?
3 Is ....?
answers table
id question_id answer
1 1 54
2 1 11
3 1 22
4 2 England
5 1 5
6 2 Turkey
how to select questions that have answers less than 4?
thanks,
select questions.id, questions.question from questions
inner join answers on questions.id = answers.question_id
group by questions.id, questions.question having count(questions.id) <4
here you go.
use this :
SELECT *
FROM questions
WHERE id in
(
SELECT question_id
from answers
group by question_id
having count(question_id) <4
)

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

Mysql select records from 2 rows

I have a table include some data like that. This is example for question/answer script. ID is auto increment and if PID=0 then it is question, when reply any question then PID is set to question's ID. There is no Subject for replies.
ID PID SUBJECT CONTENT DATE
1 0 First Question This is my first 09/01/2013
2 0 Second Question This is second 09/01/2013
3 1 Yes this is first 09/01/2013
4 2 I agree this is second 10/01/2013
5 0 Third Question This is third question 11/01/2013
6 1 Reply to first 11/01/2013
7 1 Another reply to first 12/01/2013
8 5 This is reply of 5th 13/01/2013
9 2 Last try for second 14/01/2013
My questions are,
How can I select questions with reply count?
Ex.
First Question (3)
Second Question (2)
Third Question (1)
How can I select today's answered questions or answers?
Ex. For 09/01/2013
First Question (2) ---> 1 question and 1 answer but 2 actions
Second Question (1) ---> just 1 question
Select the questions and join against the answers:
select q.id, q.subject, count(a.id)
from yourtable q
left join yourtable a on q.id=a.pid
where q.pid=0
group by q.id;
Try join for first task
SELECT
q.id as ID,
q.pid as PID,
q.subject as SUBJECT,
COUNT(lq.id) as Total
FROM questions as q
LEFT JOIN questions as lq ON lq.pid = q.ID
WHERE q.PID = 0
GROUP BY q.id
OUTPUT
ID PID SUBJECT TOTAL
1 0 First Question 3
2 0 Second Question 2
5 0 Third Question 1
Demo
EDITS :
For second part. You should note that there can be many other ways for doing the same task.
SELECT
q.id as ID,
q.pid as PID,
q.subject as SUBJECT,
(COUNT(lq.id) - 1) as Total,
q.date
FROM questions as q
LEFT JOIN questions as lq ON lq.pid = q.ID OR lq.id = q.PID
WHERE q.date = DATE(NOW())
OUTPUT
ID PID SUBJECT TOTAL DATE
1 0 First Question 2 January, 09 2012 00:00:00+0000
2 0 Second Question 1 January, 09 2012 00:00:00+0000
Demo
For question 1
select PID,count(*) from table
where pid<>0
group by PID
For question 2
select PID,count(*) from table
where pid<>0 and date=current_date()
group by PID

mysql subquery issue on comments voting

I have MySQL query which I think needs a subquery. I'd like to count the total number of "up" votes on each of many comments and determine whether a given user has already voted on each comment:
Here are my tables:
Comments Table:
comment_id comment acct_id topic_id comment_date
5 hello5 2 1 9:00am
7 hello7 3 1 10:00am
Votes Table:
comment_id vote acct_id topic_id
5 1 1 1
7 1 4 1
5 1 5 1
here's the output i'm getting:
comment_id commenter comment voter sum did_i_vote
5 2 hello5 1 2 1
7 3 hello7 4 1 1
Here's the desired output:
comment_id commenter comment voter sum did_i_vote
5 2 hello5 **5** 2 1
7 3 hello7 4 1 1
Here's my query:
SELECT votes.acct_id as voter, comments.comment_id, comment, comments.acct_id as
commenter, SUM(vote) as sum, vote as did_i_vote
from votes
right join comments
on votes.comment_id=comments.comment_id
join accounts on comments.acct_id=accounts.acct_id
where topic_id=1
group by comments.comment_id order by comment_date desc
You'll notice these 2 outputs are identical except for voter.
What my query is missing is a way to determine whether a given user, for example with voter=acct_id=5, was the one who voted on any of the comments. Without that condition, the query picks the first voter in the list which for comment_id=5 is voter=1.
So my question is I think I need to insert the following subquery:
SELECT from votes where voter='X'
I'm just not sure where or how. Putting it in parentheses in between the from and votes above eliminates the sum() function so I'm stuck.
Any thoughts?
If I've understood you correctly from your comments above, I think all you need to do is (outer) join the votes table to your query another time, this time only on the votes of the account in question:
SELECT
comments.comment_id AS comment_id,
comments.acct_id AS commenter,
comment AS comment,
-- votes.acct_id AS voter, -- ambiguous
SUM(votes.vote) AS sum,
my_votes.vote IS NOT NULL AS did_i_vote
FROM
votes
RIGHT JOIN comments ON votes.comment_id=comments.comment_id
JOIN accounts ON comments.acct_id=accounts.acct_id -- what purpose ?
LEFT JOIN votes AS my_votes ON
my_votes.commentid=comments.comment_id
AND my_votes.acct_id=#my_acct_id
WHERE topic_id = 1 -- ambiguous
GROUP BY comments.comment_id
ORDER BY comment_date DESC

select questions which doesnot have answers

I have a simple query doubt.
Question Table
qid question
1 ques1
2 ques2
3 ques3
4 ques4
5 ques5
6 ques6
7 ques7
Answer Table
ansid qid answer
1 1 ans1
2 2 ans2
3 2 ans3
4 4 ans4
5 6 ans5
I have two tables. One for questions and one for answers. Question id(qid) is use as a foreign key in answer table. I want select questions which doesnot have an answer in the answer table. In the above example I need questions 3,5,7. My database is large it may contain more than 50,000 records.
Thanks
ARun
select q.* from question as q
left join answer as a
on q.id = a.qid
where a.qid is null
edit.
Moreover it would be better to add an index on answer table
alter table answer add index iq (qid);
select * from question where qid not in
(select qid from answer)