On my website I have a page where users can answer one question at a time.
The questions that are provided are stored in the questions table.
When the user answers a question it gets stored in the answers table.
After answering a question it moves on to the next question.
The way my code works right now is it selects a question from the questions table and then joins the answers table WHERE answers.id IS NULL. (the user hasn't answered this question.)
The way I need it to work is similar to above, except it needs to also check if the question has been answered by the user, and if it has don't display it and move on to the next question the user hasn't answered.
I hope I've explained myself well enough.
The code I'm currently using
$db = db_open();
$query = "SELECT
questions.id,
questions.question
FROM questions
LEFT JOIN answers ON questions.id = answers.question
WHERE answers.id IS NULL
GROUP BY questions.id";
$result = db_query($db,$query);
$result = db_fetch_array($result);
$default_question = array("id"=>$result["id"],"question"=>$result["question"]);
Question table
id question
1 This is a question
Answer table
id user question answer
1 1 1 This is an answer
Try with this:
$user_id = getUserIdOrSomethingLikeThat();
$query = "SELECT
questions.id,
questions.question
FROM questions
WHERE NOT EXISTS (
SELECT * FROM answers WHERE answers.question = questions.id AND answers.user = $user_id
)
Also consider to refactor your table definitions. A the column names are confusing. Something like this would be better:
question table fields: id, body
answer table fields: id, question_id, user_id,body
Related
I need help building a MySQL query to query 3 tables.
I am building an online quiz with stored answers in MySQL and PHP. I am using 3 tables for the user, questions and answers. I want to provide the users with questions that they've not answered previously but can't get the query to work.
The database table structures are as follows:-
Users
user_id
language
+ other things
questions
id
question_number
text
language
answers
answer_value
id
question_number
user_id
I can obtain the answers that they have completed by using
SELECT questions.question_number, questions.text
from questions
JOIN answers ON answers.question_number=questions.question_number
JOIN users on users.user_id=answers.user_id
WHERE questions.language=users.language AND users.user_id='1'
This returns the text for the questions answered but I want to obtain the question number and text for the questions that they haven't answered. I think I've pulled all my hair out trying to solve this one. Any help greatly appreciated.
I've solved it thanks by using
SELECT DISTINCT questions.question_number, questions.text FROM questions WHERE questions.question_number NOT IN(SELECT answers.question_number FROM answers WHERE answers.user_id=$var)
I'm creating a way that a "teacher" could make an exam and the "student" can take an exam.
First off, it is also possible for a teacher to make new questions, using this query:
INSERT INTO questions (question, type) VALUES ('$question', '$type')
In the database, I set questions to also have question_id which is auto incremented after each entry. Then on a separate page, they can pick which questions they would like to add to the exam. So I just:
SELECT * FROM questions
Then there is a checkbox for them to check which questions to add the use this query:
INSERT INTO exams (question_id) VALUES ('$question_id')
The table exams also has an auto incremented exam_id.
So now I would like to display the questions the teacher picked, but I don't even know what type I should store question_id in exams (right now it is INT) so I can loop through them.
ie. Teacher picks questions 1,2,4,10 and query for getting the question would look like
SELECT question FROM questions WHERE question_id='1,2,4,10'
Assuming you are getting the question id by POST or GET, Try this:
$selected = implode(',', $_REQUEST['selectedquestionids']);
SELECT question FROM questions
WHERE question_id IN ($selected)
GROUP BY question_id;
Hope this may help.
So I'm trying to make some kind of webapp quiz.
People will be able to submit their own questions to a database and will be able to take a quiz of 10 random true/false questions.
I want to write an sql select to get questions that are :
1- not uploaded by the logged in user
2- not yet answered by the logged in user
At the moment I have this: ($userid = logged in user id)
public function selectNewRandom($userid){
$sql = "SELECT `questions`.`id`, `questions`.`quest`, `questions`.`answ`, `questions`.`uploader_id`,`answers`.`item_id`, `answers`.`user_id` FROM `questions` LEFT JOIN `answers` ON `questions`.`id` = `answers`.`question_id` WHERE `questions`.`uploader_id` != $userid AND (`answers`.`user_id` IS null OR `answers`.`user_id` != $userid) ORDER BY RAND()";
$stmt = $this->pdo->prepare($sql);
$stmt->bindValue(':id', $id);
$stmt->execute();
return $stmt->fetch(PDO::FETCH_ASSOC);
}
To get 1 new question that doesn't break the above rules.
My database layout is:
QUESTIONS
-id
-quest
-answ
-uploader_id
ANSWERS
-id
-question_id
-user_id
-answered (1/0 true false)
This works fine for the first user, he is only getting unique and unanswered questions.. But as soon as a second one logs I think what the command is doing is:
he finds the question_id in the answers table, sees a user_id that is different and stops checking and just allows that question to be returned, even when he also answered the question but the sql never checks. ? so is there maybe a way to check if there is not 1 entry in the answers table that has both the question_id that equals the question id and user_id that equals the $userid (=$_SESSION['user']['id'])
Is there any way to fix this, write another SELECT query or to do it a different way, php maybe?.. (returning an array of 10 questions is also ok..)
[SUMMARY]
It has te check every item with the questions id in the answers table and if one of them has a user_id equal to the logged in user, exclude that item from the result. it works fine if the answered table is empty, showing no more new questions in the end...But if you then log in with another user, no questions that are answered are excluded.
You need to compare the answer's userid in the ON clause.
SELECT q.`id`, q.`quest`, q.`answ`, q.`uploader_id`, a.`item_id`, a.`user_id`
FROM `questions` q
LEFT JOIN `answers` a
ON q.`id` = a.`question_id` AND a.`user_id` = $userid
WHERE q.`uploader_id` != $userid AND a.`user_id` IS NULL
ORDER BY RAND()
You could also write this with EXISTS, but I prefer to use JOIN myself.
Basically, what this says is, "Give me all the questions left joined with answers from our user (ignoring answers from anyone else). Then throw away questions uploaded by our user, and throw away questions that have an answer."
That leaves you with what you want -- questions not uploaded or answered by your user.
there might be issue with creating join using PHP's PDO library, i suggest write simple join query and executed it via my_sqli library. Sometimes binding of parameters arise such issues.
Before I ask my question, I just wanted to thank everyone that replied to my question yesterday -> Countdown using javascript.
Idea:
I created a quiz using php, but I would like to create a MySQL Database and having a table with all the questions, answers and multiple choice stored inside.
Issue:
Since the quiz is multiple choice, I don't know how to go about storing the multiple choice options in the table. Could I store the options and have each answer separated by a special character and let php get the string and separate the options?
Ex: Question: What is your favorite color? Options: Blue=Red=Purple=Yellow.(Database View)
What do you folks think is the best practice for something like this?
I think the best practice would be to use multiple tables. One for the question and one for answers. The answer table would contain question_id as well as a flag whether or not it is the correct answer
It could look like this
TABLE questions
FIELDS: id, text
TABLE answers
FIELDS: id, question_id, text, correct
The problem with using one field for all the answers is that you could accidently use the character you use for splitting inside the text of an answer
simply, create two tables:
questions
question_id, question
answers
answer_id, question_id, answer
Now, you can link these two tables using question_id
There are a couple of ways around this :
The "proper" way is to create another table ( so that you have a table called "questions", each of which have a unique id, and another called "answers", where each has the question id )
The "simple" way, which is to use JSON ( see json_encode and json_decode ) which takes care of using special characters etc in a field
You'd have a questions table, like this:
id | question
0 Do you even lift?
id would be INT(11) PRIMARY_KEY AUTO_INCREMENT while question would just be TEXT. Then, you would have an answers table:
id | question_id | answer
0 0 Yes
1 0 No
2 0 Maybe
Here, question_id refers to the ID of the question in the questions table. These answers all belong to one question. This is called a Has many relationship, as one question has many answers.
This is how its usually done. Implementing it is not that hard, even if you're not using a framework (most of them do the work for you).
Hope this helps
Tables:
quiz
quiz id (pk)
quiz info (other columns)
questions
question id(pk)
quiz id
question text
answers
answer id(pk)
question id
answer text
To display a given question do a join on the quiz, question and answers.
EDIT: You could either add a column for 'right/wrong answer (0/1)' or have another table:
solutions
solution id(pk)
question id
answer id
I didn't put the 'correct answer' in the answers table as that's not good normalization.
There could be many possible schema designs for this but my suggestion is like this:
Don't ever store values separated by comma on the tables.
This table holds the quizzes.
Quiz Table
QuizID (PK)
other columns..
This holds the questions for every quiz.
Question Table
QuestionID (PK)
QuestionDetail
QuizID (FK)
other columns...
This holds the answers.
Answer Table
AnswerID (PK)
AnswerDetail
This holds the correct answer for every question on each quiz or in other words, this is the answer key.
Question_Answer_Correct Table
QuestionID (FK) -- also a compound primary key with AnswerID
AnswerID (FK)
This contains list of users.
User Table
UserID (PK)
UserName
other columns...
This contains answer of users on a specified question. There is no QuizID here since the questions are already connected on the quiz table.
User_Answers Table
UserID (FK)
QuestionID (FK)
AnswerID (FK)
I am trying to make a quiz that should show questions not answered before by the same user.
Therefore, a session is created when a user starts the quiz.
Here is the situation:
There is a table "Questions"
This table contains all questions. There is a unique field QuestionId.
The questions always have a CategoryId from 1 to 5
There is a table "Answers"
This table contains all answers given by users. The session id is stored in SessionId, the answered question id is stored in QuestionId.
I now am looking for a query that
Fetches a question from Questions
Where Category Id = X
That has not been answered before (so the QuestionId should not be listed in Answers with the same SessionId)
My own trials and some Googling did not help. Hope somebody here can help me out.
Thanks in advance!
Try this:
select
*
from
question
where
categoryid = x and
not exists (
select
'1'
from
answers
where
sessionid = y and
answers.questionid = question.questionid
)
It will list all questions that don't have an answer from the user. You can put a "limit" on the results to get back only 1 row if that's what you need.