How to structure/normalize this database? - mysql

I need to make a database that should hold 50 questions, 3 possible answers for each question and value of each answer.
This is my first guess but it feels wrong and I'm not sure how to access this values properly.
Any suggestions on how to structure this?
This seems like correct way:
questions table
---------------
id
title
...
answers table
-------------
id
question_id
answer
value

One way would be
questions table
---------------
id
title
...
values table
------------
id
value
answers table
-------------
id
question_id
answer
value_id
Then to get all answers of a specific question do
select a.*, v.value
from answers a
join questions q on q.id = a.question_id
join values v on v.id = a.value_id
where q.title = 'what is the name of Dr. Who'

questions
----------
id
title
answers
--------
id
question_id
answer
value
This query would give you all the questions with their possible answers, with the answers listed from best to worst (assuming value is a "points" system, and not a description of quality like "Good" "Better" "Best").
SELECT *
FROM questions AS qTbl
LEFT JOIN answers AS aTbl ON qTbl.id = aTbl.question_id
ORDER BY qTbl.title, aTbl.value DESC
;

Related

Count statement in phpmyadmin

I have 3 tables (user, questions, answers) in the question table i have id_question and question, in the answer table I have id_question, user_id and answer. I want to run a query that gives me the number of answer's per question.
I want a column that has all questions that were answered (not the id_question) and 3 other columns (yes, no, maybe) that have the number of times that that answer was given to a question. The question column can't have repeated questions (even though users can answer the same questions and give different answers, I want the number of yes, nos and maybes to each question). I'm only created the yes column, having trouble in creating the other 2
Here's what I did so far:
SELECT
questions.question, COUNT(answers.answer) As Yes
FROM
answers
INNER JOIN
questions ON questions.id_question = answers.id_question
WHERE
answer = 'yes'
GROUP BY
question
ORDER BY
questions.id_question ASC
SELECT questions.question,
SUM(IF(answer='yes', 1, 0)) AS Yes,
SUM(IF(answer='no', 1, 0)) AS No,
SUM(IF(answer='maybe', 1, 0)) AS Maybe
FROM answers
INNER JOIN questions ON questions.id_question=answers.id_question
GROUP BY question
ORDER BY questions.id_question ASC

Selecting multiple values from multiple tables

MySQL.
I have two tables, one is "Questions" and the other is "Answers"
The Questions table:
- question_id
- user_id
- question
The Answers table:
- answer_id
- question_id
- user_id
- answer
- correct
The goal is to get all questions (and associative answers) based on a user's id. I've been able to get all of the answers, however I'm only getting one question. I can see why it's only getting a single question, but I don't have any idea how to go about getting the question text for each answer.
Here's the code that I'm using right now. Where id_in is an input value on a saved procedure. The issue is that it gives me all of the answers for each question, but all of them return the same question text. I feel like possibly a type of join would be better here, but we haven't started learning about them yet and I hardly know anything about them as is.
BEGIN
DECLARE question_text VARCHAR(40);
SELECT question INTO question_text FROM questions WHERE user_id = id_in;
SELECT question_text, Q.* FROM answers AS Q WHERE user_id = id_in;
END
Yes, this is homework. I'm just completely lost as to what I need to be doing.
Left joins allow for All things in the left table, and only the matching things in the right table. In my example I may have A and Q mixed up but I think this is the general gist of it. You can also take the user_id = in_id and move that to a wear, but filter on the join should be faster.
SELECT
Q.QUESTION
, A.ANSWER
, A.CORRECT
FROM ANSWERS A
LEFT JOIN QUESTION Q
ON A.QUESTION_ID = Q.QUESTION_ID
AND A.USER_ID = Q.USER_ID
AND A.USER_ID = ID_IN
AND Q.USER_ID = ID_IN

MySQL joining table to itself and comparing results

MySQLFiddle here: http://sqlfiddle.com/#!2/15d447/1
I have a single table I am trying to work with:
Table 1: user_answers table (stores users answers to various questions)
The notable values that are stored are the users id (column uid), the question id for the question they are answering (column quid), the answer to the question (column answer) and the importance of their answer (column importance).
The end result I want:
I'd like to be able to grab all the questions that any two users have answered, excluding any answers from questions that have either not been answered by the other party, or answers to the same question which have a value of 1 for either user in importance. Again, this will only ever be used to compare two users at a time.
I've been pretty unsuccesful in my attempts, but here is what I've tried, just piecing things together:
#attempt one: trying to exclude answers that were not answered by both users
SELECT * FROM user_answers AS uid1
JOIN user_answers AS uid2 ON uid1.uid = uid2.uid
WHERE uid1.uid = 1
AND uid2.uid = 20008
AND uid1.quid IS NOT NULL
AND uid2.quid IS NOT NULL;
This returns no results but I'm not exactly sure why.
#attempt two: trying to exclude where answers are the same for both users
SELECT * FROM user_answers AS uid1
LEFT JOIN user_answers AS uid2 ON (uid1.uid = uid2.uid AND uid1.answer <> uid2.answer)
This gives me results, but seems to be doubling up on everything because of the join. I also tried in this attempt to eliminate any answers what were the same, which seems to be working in that sense.
Any guidance is appreciated.
Thanks.
You can answer your question using an aggregation query. The idea is to using the having clause to filter the rows for the conditions you are looking at.
Because you are not interested at all in questions with importance = 1 those are filtered using a where clause:
select ua.quid
from user_answers ua
where importance <> 1 and uid in (1, 20008)
group by ua.quid
having sum(uid = 1) > 0 and
sum(uid = 20008) > 0;
If you want to include the answers, you can do:
select ua.quid,
group_concat(concat(uid, ':', answer) order by uid) as answers
Just a simple version of what you need.
select *
from user_answers a,
user_answers b
where a.quid = b.quid
and a.uid <> b.uid
and 1 not in (a.importance, b.importance)
If you like to filter just the questions just change the * for distinct a.quid
See it here on fiddle: http://sqlfiddle.com/#!2/15d447/15

MYSQL - Creating a Temporary Column that Indicates If Questions are Answered

Hi I'm currently developing a sort of quiz application. In "Discover" section I get popular and latest questions. But when I get them I should also check if question is already answered by current user or not.
Here are my tables:
questions: (media_id is primary key, player_id is creator of the question)
media_id - player_id - answer0 - answer1 - ...
answers: (media_id is primary key, player_id is the person who answers the question)
media_id - player_id - result - ...
This is how I get popular questions:
select * from questions where order by popularity_count
EDIT:
Let me show what I want to achieve by examples:
questions rows:
media_id - player_id - answer0 - answer1
0123456 abc123 bla bla
6543210 hjk789 lor ips
answers rows:
media_id - player_id - result
6543210 abc123 1
So when user "abc123" gets the popular questions results should be:
media_id - player_id - answer0 - answer1 - is_answered
0123456 abc123 bla bla 0
6543210 hjk789 lor ips 1
The problem is I need a temporary column in the result of query that indicates if question is replied by the current user or not. How can I achieve this?
I can find if question is already answered or not for popularity section by using two queries. First I get the popular questions then I simply check if question is answered or not for every questions which seems so ineffective way. How can I achieve this with only one query?
Thank you!
It doesn't seem you are approaching this problem correctly as you have a non-normalized table structure.
You should have a separate table that contains the answers by row.
questions (id, media_id, player_id, question)
answers (id, media_id, player_id, question_id, answer)
This way you can LEFT JOIN answers to questions and easily see which questions are not answered like so:
SELECT q.question, a.answer
FROM question q
LEFT JOIN answers a ON a.question_id = q.id
AND a.media_id = q.media_id
AND a.player_id = q.player_id
See it in action
To add a column to your current query, you can append it to your SELECT and use a CASE statement to check whether it's been answered.
SELECT ...,
CASE
WHEN answer0 IS NOT NULL
THEN 'Yes'
ELSE 'No'
END AS 'Answered'
FROM ...
Update
Based on your update, it seems as though you are only JOINing on player_id. I believe you intend to JOIN on both player_id and media_id. See the difference between the data you provided and what I think you intend it to be.

mysql Join Query for Result from two table

I have Two Table One to store Questions and Other to store Replies to Questions as Below
I have Shown the Table Structure and Column in table as Below
Question Table
Question_Id(PK) | Question | Name | EmailAddress
Answer Table
Answer_Id | Question_Id | Question | Name | EmailAddress
What ever question is posted it will be added to Question table and What ever Replies people post will be added to answer table
Now when ever Some one post a Reply to Question I Should Send mail to one who Posted Question and to those who posted Replies to the Question
Please Suggest a mysql Query for the above
Thank you
In theory you should know in the application the id of the question (qid) someone is replying to. Based on this id you can issue the following query:
Select EmailAddress from Question where Question_Id=qid
Union
Select EmailAddress from answer where Question_id=qid
Depending on the logic of your application this might also select the address of the current user. If you want to avoid this you should include in both select statments a condition to exclude the current replier. Something like:
Select EmailAddress from Question where Question_Id=qid and EmailAddress!=curentUserAddress
Union
Select EmailAddress from answer where Question_id=qid and EmailAddress!=curentUserAddress
Select *
from questions
left join answers
on questions.id = answers.question_id
where question_id = 1
select * from Question q, Answer a
where q.Question_Id = a.Question_id and
q.Question_Id = question_id