MYSQL php couple of tables not working - php

Please Read this carefully so you understand the question. This question is for an assignment in University.
There are two tables, one is an Answer table and the other is a StudentAnswer table. There are 6 fields I am interested in, 4 in Answer table and 2 from StudentAnswer table. Below are tables and their fields and data.

I believe that left join is what you are looking for.
SELECT * FROM `StudentAnswer` as sa
LEFT JOIN (SELECT * FROM `Question` WHERE correct = 1) as q
ON `sa`.Questionid = q.id

You need to look at subqueries in mysql your eventual answer will probably look somethink like this ...
SELECT * FROM Question q
INNER JOIN (SELECT sa.QuestionId, sa.StudentAnswer, at.AnswerContent FROM StudentAnswer sa LEFT JOIN Answer at ON (sa.StudentAnswer = at.AnswerId AND sa.QuestionId = at.QuestionId) sq ON q.QuestionId = sq.QuestionId
JOIN Answer a ON sq.QuestionId = a.QuestionId
WHERE
(CorrectAnswer = '1')
ORDER BY $orderfield ASC
But without a full schema I can't really help, I would also say be careful all my tutors at uni (Huddersfield) were notorious for searching places like this for snippets of their assignments, so I hope this has helped without getting you into trouble

You can join to Answer more than once in your query, just make sure you give it a different alias. The combination of WHERE clause and JOIN condition you have now gets you the correct answer for a question; think about how else you can relate StudentAnswer and Answer.

Related

join three tables for nested report

I am trying to find a way to properly write a query to get the student answers for each question. I am not very good with SQL so I appreciate any help. This is for a student report I am building in PHP/MySQL
Firstly I have a question_table which stores the questions.
structure is:
id
question
Then I have a student table which has the student details.
structure is
id
student_name
Then I have an answers table, which contains each question_id and student_id.
structure is:
id
question_id
student_id
answer
I want to create a report where for each listed question. It shows the answer for each student. Something like:
Question: What is the name of the largest planet in the Solar System
Student A: Jupiter
Student B: Jupiter
Student C: Saturn
I have tried below but it does not work correctly...:
select * from question, student
inner join answer
where answer.question_id = question.id
Another challenge is that the report should be paginated. So first 20 questions per page. If a question has multiple student answers then the count will be more and I am not sure how I can paginate this correctly :(
You seem to want two joins. This gives you one row per question/student:
select q.question, s.student_name, a.answer
from answers a
inner join questions q on q.id = a.question_id
inner join students s on s.id = a.student_id
order by q.id, s.id
You can implement the pagination logic with window functions (available in MySQL 8.0):
select *
from (
select q.question, s.student_name, a.answer,
dense_rank() over(order by q.id) rn
from answers a
inner join questions q on q.id = a.question_id
inner join students s on s.id = a.student_id
) t
where rn between ? and ?
order by q.id, s.id
The two question marks represent the range of questions you want. The first question has index 1, and so on.
For pagination logic you have to use LIMIT keyword.It's supported to your server version.
Query like :
SELECT q.question, s.student_name, a.answer
FROM answers a
INNER JOIN questions q ON q.id = a.question_id
INNER JOIN students s ON s.id = a.student_id
ORDER BY q.id, s.id LIMIT 0,20
Now, you will get record 0 to 20.
Using of this you have to specify there are more data for get if yes then call next page and your LIMIT 20,20(have to make your own calculation For get offset according to pagination)
If there are no data for next page then stop execute query.

JOIN or subquery in SQL to grab data out of various tables needed

I need to pull out some data from various tables using PHP prepared statements and MySQL.
The items I need to plot the data into a graph are:
tblstudent.studentID
tblquestionnaire.questionnaireID
tblstudentAnswer.answer
The database design looks like this with my table joins.
I have attempted to use INNER JOIN's, however I cannot join tblquestionnaire into it as I do not share a key with that table and the student table or with the studentAnswer table.
Any guidance would be much appreciated in how I get those pieces of information out within an SQL query.
You are overthinking it.
to get all student Ids, with their answers and the questionaire ID.
The following query is enough.
SELECT
sta.studenID
,qq.questionnaireID
,sta.answer
FROM
studentAnswer sta
INNER JOIN
questionnaireQuestions qq ON sta.questionnID = qq.questionnID
First of all, you don't need the questionnaire table to get questionnaireID - questionnaireQuestions contains it and it can be directly linked to studentAnswer. Second of all, you don't need the students table to get studentID because studentAnswer contains it. So you can simply follow this logic:
you can get questionnaireID from questionnaireQuestions
you can link questionnaireQuestions with studentAnswer through questionID to get answer and studentID
This bring us to a simple join of two tables:
SELECT sa.studentID, qq.questionnaireID, sa.answer
FROM studentAnswer sa
INNER JOIN questionnaireQuestions qq
ON qq.questionID = sa.questionID
The point is - always look for the shortest route to extract your data. Don't involve any extra tables if it can be avoided. This is where your diagram will come in handy. Looking at it, you can see that questionnaireQuestions is "closer" (one step less to connect) to studentAnswer than questionnaire. Since it contains the data you need, it's logical to use it over questionnaire.
Now let's say you needed questionnaireName along with firstName and lastName of the student. Even though you can't directly join questionnaire to student, you can do it through questionnaireQuestions and studentAnswers. Joins can contain tables you're not selecting from - it's a mechanism of connecting data. Then you'd follow this logic:
you can get questionnaireName from questionnaire
you can link questionnaire to questionnaireQuestions through questionnaireID
you can link questionnaireQuestions to studentAnswer through questionID
you can link studentAnswer to student through studentID
This brings us to a query like this:
SELECT q.questionnaireName, s.firstName, s.lastName
FROM questionnaire q
INNER JOIN questionnaireQuestions qq ON qq.questionnaireID = q.questionnaireID
INNER JOIN studentAnswer sa ON qq.questionID = sa.questionID
INNER JOIN student s ON s.studentID = sa.studentID

Fetch questions that the logged in user hasn't answered yet using PHP and MYSQL

I want to fetch and display a limited amount of questions that hasn't been answered yet by the logged in user only.
I already have this block of code, but I can't seem to find out how to select it distinctly for a certain logged in user.
SELECT
a.*
FROM
questions as a
LEFT JOIN
questions_answers as b
ON (a.q_id = b.q_id)
WHERE
b.q_id IS NULL
AND b.user_id = 2
ORDER BY
RAND() LIMIT 10
assuming "2" is a sample user ID of the logged in user.
The "AND b.user_id = 2" is where I'm stuck.
I'll appreciate any help.
UPDATE:
Here's the table structure
Questions Table
q_id
question
Questions_Answers Table
ans_id
q_id
user_id
UPDATE:
I have already answered this question and added it below. Thank you to everyone who suggested. I'll take your advice seriously as well. I'll appreciate it if you will upvote my answer if you have tried it and get what I meant. :)
You can use left join with
SELECT a.*
FROM questions as a
LEFT JOIN questions_answers as b ON (a.q_id = b.q_id)
WHERE b.q_id IS NULL
AND b.user_id = 2
Please check below link How to select all records from one table that do not exist in another table?
I am little bit confused about your tables structure however i tried to answer it assuming you are storing answers and answering users_id in answers table -
Update: Thanks for providing table structure please see below update query.
SELECT questions.*, questions_answers.*
FROM questions
LEFT JOIN questions_answers ON questions.q_id = questions_answers.q_id
WHERE questions_answers.user_id <> '2'
OR
SELECT questions.*, questions_answers.*
FROM questions
LEFT JOIN questions_answers ON questions.q_id = questions_answers.q_id
WHERE NOT(questions_answers.user_id = '2')
And so, after a few trials (thanks to everyone who posted their suggestions), I was able to manage to get the data I am wanting for using the following block of code. :)
SELECT
a.*
FROM
questions as a
LEFT JOIN
questions_answers as b
ON (a.q_id = b.q_id) AND b.user_id = 2
WHERE
b.q_id IS NULL
ORDER BY RAND()
LIMIT 10
Sharing this so everyone who stumbles down on my post will get the correct answer. I'll appreciate if you will upvote this one if you have tried the code and got the answer. :)
SELECT
a.*
FROM
questions as a
WHERE
a.q_id not in(select q_id from questions_answers where user_id = 2)
ORDER BY
RAND() LIMIT 10
You can achieve this by simple inner query. I hope this will help you.
sqlfiddle : http://sqlfiddle.com/#!9/fee4ba/8
Or
SELECT * FROM (SELECT
a.* ,b.ans_id
FROM
questions as a
left JOIN
questions_answers as b
ON (a.q_id = b.q_id) AND b.user_id = 2 ) as c
WHERE c.ans_id IS null
ORDER BY
RAND() LIMIT 10

MySql operator complexity

I have a pet project on feedback system with to tables, one caputres the questions of customers and another caputures the answeers of help desk.
////////////////////////////////////////////////////////////////////////
Customers_Question table AND helpdesk_answers includes:
Qst_id(pk), Qst_id(pk)(FK)
qst_title, helpdesk_answer
qst_comment,
qst_customer_name,
qst_date
to get answers mysql query is:
SELECT*from customers_question, helpdesk_answers
WHERE customers_qst.Qst_id = helpdesk_answers(FK Qst_id)
i get all questions that already answered.
QUESTION: HOW DO I GET OR COUNT UNANSWERED QUESTION?
SELECT q.*
from customers_question q
left join helpdesk_answers a on q.Qst_id = a.Qst_id
where a.Qst_id is null
See this great explanation of joins
using IS NULL ->
SELECT cq.* FROM customers_question cq
LEFT JOIN helpdesk_answers ha
ON cq.Qst_id = ha.Qst_id
WHERE ha.Qst_id IS NULL
OR
using NOT IN() ->
SELECT * FROM customers_question
WHERE Qst_id NOT IN
(SELECT DISTINCT Qst_id FROM helpdesk_answers)
You can use the code given in the other answers to get the questions.
In order to count the rows returned you can see this answer.

Complex (ish) SQL join and count query

I'm trying to create a simple poll function using php and sql.
I have three tables:
Questions
Which simply contains each question asked
question_id | question_text | created_at
Answers
Which contains each answer for each question
question_id | answer_id | answer_text
Answered Questions
Which records who has voted for each option
question_id | answer_id | user_ip
I'm trying to write a query which will return a single question (the most recent) along with all the possible answers to that question and finally a count of each answer to each question. I know I will have to use a GROUP BY clause and possible LEFT OUTER JOIN, but the exact syntax is eluding me atm.
Any advice would be greatly appreciated. Thanks.
This is very similar to the logic in this article http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/.
Essentially you need a subquery which selects the single record / question you are interested in, as well as an outer query to select the information related to that record that you are interested in
(I could post another SQL statement to add to the nice collection that have already been posted, but I thought I'd try and shed some light onto how the other posted queries work)
This query should work on most DBMSs:
select q.question_id, question_text, a.answer_id, a.answer_text, count(user_ip)
from questions q
inner join answers a on (q.question_id = a.question_id)
left join answered_questions aq on (a.question_id = aq.question_id
and a.answer_id = aq.answer_id)
where created_at = (select max(created_at)
from questions
)
group by q.question_id, a.answer_id, q.question_text, a.answer_text
Assuming you're usnig MySQL:
SELECT q.* ,
(
SELECT COUNT(*)
FROM answered_questions aq
WHERE aq.answer_id = a.answer_id
AND aq.question_id = q.question_id
) AS votes
FROM (
SELECT *
FROM question
ORDER BY
created_at DESC
LIMIT 1
) q
LEFT OUTER JOIN
answers a
ON a.question_id = q.question_id
SELECT
questions.question_id,
questions.question_text,
answers.answer_id,
answers.answer_text,
COUNT(answered_questions.user_ip)
FROM
questions,answers,
answered_questions
WHERE
questions.question_id=answers.question_id
AND
questions.question_id=
(SELECT
question_id
FROM questions
ORDER BY questions.created_at
LIMIT 1
)
AND
answered_questions.question_id=questions.question_id
GROUP BY
questions.question_id
should work (although I haven't tested it).

Categories