Display data from multiple tables in MYSQL database - php

I know there's something wrong here. Can anyone point it out? I am trying to display question_body from questions and answers_body from answers.
EDIT : I got this error: Column 'question_id' in field list is ambiguous
<?php
$auctionSurvey = "SELECT question_id, survey_id, question_body, answer_body FROM questions
INNER JOIN answers ON answers.question_id = questions.question_id
WHERE survey_id='1'";
$aucResult = mysql_query($auctionSurvey) or die (mysql_error());
while($auctionRow = mysql_fetch_assoc($aucResult)){
echo $auctionRow['question_body']. $auctionRow['answer_body'];
}
?>

It looks like one problem is ambiguous column...
In the SELECT list, I don't think MySQL can figure out which table is referenced by question_id.
The normative pattern whenever two (or more) tables (row sources) are referenced is to QUALIFY every column reference...
SELECT q.question_id
, q.survey_id
, q.question_body
, a.answer_body
FROM questions q
JOIN answers a
ON a.question_id = q.question_id
WHERE q.survey_id='1'
There's two big benefits to this pattern (qualifying column references):
Firstly, it helps future readers "know" which columns are from which table, without having to look at the table definitions and figure out which table has which column name.
Secondly, it helps avoid "breaking" a SQL statement when a new column with the same name as a column in another table is added... having the column references qualified avoids the potential for breaking a SQL statement (causing a working SQL statement to start raising an ambiguous column exception.

Your error indicates that 'question_id' is in both tables. Use an 'alias' to differentiate between the tables, like this:
SELECT Q.question_id, survey_id, question_body, answer_body
FROM questions Q
INNER JOIN answers A ON A.question_id = Q.question_id
WHERE survey_id='1'";

You have to differentiate between the two tables:
SELECT Q.question_id,
A.question_id,
Q.survey_id,
Q.question_body,
A.answer_body
FROM questions Q
INNER JOIN answers A ON A.question_id = Q.question_id
WHERE Q.survey_id='1'

Related

Is it possible with MySQL to generate a query to fetch from several tables even if one has no results?

I'm facing a problem here:
I'm building a forum, this forum has several tables and I'm trying to fetch the comments and user info in a single query.
So far, it should be easy, the problem is that I can't change the structure and with the following query I get a perfect result IF there is a like to the answer. If no one likes the answer it fails.
Select
mfr.mfr_forum_answers.id,
mfr.mfr_forum_answers.date_created,
mfr.mfr_forum_answers.last_updated,
mfr.mfr_forum_answers.content,
mfr.mfr_forum_answers.accepted,
mfr.mfr_forum_answers.user_id,
mfr.mfr_users.level,
mfr.mfr_users.avatar,
mfr.mfr_forum_likes.subject_id,
mfr.wp_users.ID As ID1,
mfr.mfr_forum_topics.user_id As owner_id,
(SELECT count(mfr.mfr_forum_likes.id) FROM mfr.mfr_forum_likes WHERE mfr.mfr_forum_likes.subject_id = :id AND mfr.mfr_forum_likes.type = 'answer') as likes,
(SELECT count(mfr.mfr_forum_likes.id) FROM mfr.mfr_forum_likes WHERE mfr.mfr_forum_likes.subject_id = :id AND makefitreal.mfr_forum_likes.type = 'answer' AND mfr.mfr_forum_likes.user_id = :sessionId ) as i_like,
mfr.wp_users.user_nicename
From
mfr.mfr_forum_likes Inner Join
mfr.mfr_forum_answers
On mfr.mfr_forum_answers.topic_id =
mfr.mfr_forum_likes.subject_id Inner Join
mfr.mfr_users
On mfr.mfr_forum_answers.user_id = mfr.mfr_users.id
Inner Join
mfr.wp_users
On mfr.mfr_users.id = mfr.wp_users.ID Inner Join
mfr.mfr_forum_topics
On mfr.mfr_forum_answers.topic_id = mfr.mfr_forum_topics.id
Where
mfr.mfr_forum_answers.topic_id = :id
And
mfr.mfr_forum_likes.type = 'answer'
So far as said it returns only if an answer has a like, I'm thinking on adding a add to the user who posts the answer by default but I'm trying to improve my skills by solving new issues.
If someone has a suggestion in how I could overcome the fact that if a table is empty, the query continues I'd be really thankfull.
Thanks in advance-
Pihh
Yes. What you are looking for are called left and right joins. According to the documentation, with a LEFT JOIN you still join two tables as normal but
If there is no matching row for the right table in the ON or USING part in a LEFT JOIN, a row with all columns set to NULL is used for the right table.
This means that you can try to join two tables, but if a row does not have any results it will still return the results from the first table. The same is true for a RIGHT JOIN only it works the opposite way: it will return results if the tabled being joined to has results, but the original table does not.
It looks like you have 3 tables for 3 relationships: there are answers, a user gives an answer, and an answer might or might not have like. To grab this data, I would suggest starting from your answers table, performing an INNER JOIN on your users table (assuming there are always users), and a LEFT JOIN on your likes table. Here is a simple example:
SELECT *
FROM answers
INNER JOIN users ON users.id = answers.user_id
LEFT JOIN likes ON likes.answer_id = answer.id
WHERE answers.id = :id
AND likes.type = 'answers'
Of course, if for some unknown reason you need to start from your likes table, then you'd have to RIGHT JOIN the other tables. I hope that gives you a good idea of how you'd make your query.

Join tables when fields aren't equal - PHP MySQL

I created two tables, one stores the questions of a quiz, and the other one stores all the answers, that users made.
The first table called "questions" contains the questions:
Field names: id|question
Eg. contents:
1|what's your fav color?
2|what's your fav animal?
The second table named "answers" stores all the answers, that users made:
Fields names: id|questionid|userid|answer
Eg. contents:
1|1|1|Red
1|1|3|Magenta
1|1|4|Green
I'd like to select those questions, that haven't been answered yet by a user.
I store the current user's id in a $_SESSION['id'] session. I tried so many ways, to get these questions, the closest query I've made, was this:
$query = SELECT questions.*, answers.* FROM questions LEFT JOIN answers ON questions.id=answers.questionid WHERE answers.id IS NULL OR answers.userid <> '.$_SESSION['id'];
This won't work, because if there's another userid in the answers table at the same question id, it still selects that row. What could be the problem? Where did I mess up my query?
Thanks in advance for all of your help!
Your user condition is in the wrong place. Since you'll want to try to find a match between the specific user and the question and detect a non match, the user part needs to go inside the ON clause with a null check in the WHERE clause;
SELECT q.*
FROM questions q
LEFT JOIN answers a
ON q.id = a.questionid
AND a.userid = YOUR_USER_ID
WHERE a.id IS NULL
An SQLfiddle to test with.

Check what values doesn't exist in SQL database

I have a question about MySQL table.
I have 2 tables (users (user_id and other rows) and answers (id, answer_id and user_id))
I would like to check, which questions the user hasn't answered (for example, in answers table exists 5 rows - 4,6,8,1,3 (but questions are 10), I would like to get out from database values 2,5,7,9,10).
How to write a query like this?
I've tried with JOIN, but nothing was successful at all!
Assuming that you have a questions and an answers table, this is the standard TSQL solution:
SELECT Q.QUESTION_ID
FROM QUESTIONS Q LEFT JOIN ANSWERS A ON Q.QUESTION_ID = A.QUESTION_ID
WHERE A.QUESTION_ID IS NULL
Or use LEFT JOIN, it's faster.
SELECT q.id
FROM question q
LEFT JOIN answers a
ON a.question_id = q.id
WHERE a.id IS NULL
not sitting in front of a mySQL DB but it should be something to the point of (you didn't tell us where your questions are listed so I put in a placeholder) It also seems like your answer table HAS to have or should have a link to the question_id it is answering. If I made any incorrect assumptions please let me know and I will edit as needed.
Select question_id from question_table
where question_id not in (select question_id from answers)
I suppose you've got a QUESTION table:
select *
from question
where not exists(
select 'x'
from answer
where answer.question_id = question.id
)
If you haven't got a QUESTION table, IMHO there's no solution

Select rows and display as columns from mySQL database

All,
I've got the following mySQL table structure:
Table dj_feedback_answers: answer_id, gig_id, question_id, answer_id
Table dj_feedback_summary: summary_id, user_id, gig_date, tip, summary, why_poor, why_fair
Table dj_feedback_questions: question_id, question_value, question_display
Table dj_feedback_ratings: rating_id, rating_value, rating_display
I'm basically asking users questions and the questions are stored in the dj_feedback_questions table and allowing them to give a rating for each question. The ratings are stored in the dj_feedback_ratings.
Each form can having variable questions so when I submit the questions I store the answers in the dj_feedback_answers. There are other more static fields on the form and those get svaed into the dj_feedback_summary. The summary_id and the gig_id are the keys that connect the two tables for the answers that the user submitted.
This means that there can be multiple rows in the dj_feedback_answers for a single row in the dj_feedback_summary table.
What I would like to do is basically be able to utilize the results in a PHP table. So I'd like my results to look something like this (assuming there are three questions in the dj_feedback_questions table):
summary_id, user_id, gig_date, tip, summary, why_poor, why_fair, question_1, question_2, question_3
1, 2, 07/23/2012, 5, This is a summary, It was poor, It was fair, 3, 4, 5
The values that would be stored for the questions would be the answer_id from the dj_feedback_answers.
I tried to create the following query to get my results. This works ok but it only can display a single question instead of all of the questions.
Select dj_feedback_summary.summary_id,
dj_feedback_summary.user_id,
dj_feedback_summary.gig_date,
dj_feedback_summary.tip,
dj_feedback_summary.summary,
dj_feedback_answers.question_id,
dj_feedback_answers.rating_id,
dj_feedback_questions.question_value,
users.first_name, users.last_name,
dj_feedback_ratings.rating_value
from dj_feedback_summary
join dj_feedback_answers on dj_feedback_summary.summary_id=dj_feedback_answers.gig_id
join dj_feedback_questions on dj_feedback_answers.question_id=dj_feedback_questions.question_id
join users on dj_feedback_summary.user_id=users.user_id
join dj_feedback_ratings on dj_feedback_ratings.rating_id=dj_feedback_answers.rating_id
where dj_feedback_questions.question_value='Overall Gig'
order by dj_feedback_summary.summary_id DESC
Is there a way to modify my query so it can return my results how I would like them?
Any advice is greatly appreciated!
Thanks
If you need values from multiple rows displayed, and it's not essential that they be in separate columns, then the MySQL GROUP CONCAT function would probably suit your purposes.
That would give you question_1, question_2, and question_3 values concatenated into a single column (if I understand your output intent correctly).
Update: To do a more "genuine" pivot (separating the answers to different questions into different columns), you could use one of the following approaches:
1) Use multiple table aliases: join to the dj_feedback_questions table one time for each question, e.g. something along these lines:
SELECT [...] FROM [...]
LEFT JOIN dj_feedback_questions q1 on q1.question_id = 1
LEFT JOIN dj_feedback_questions q2 on q2.question_id = 2
LEFT JOIN dj_feedback_questions q3 on q2.question_id = 3
You will then need to a) join to dj_feedback_answers similarly (multiple times with aliases), since you get to it via question_id, and you want different questions separated into different columns, and b) aggregate the results and decide how you want to handle nulls, since doing a regular JOIN instead of a LEFT JOIN will cause you to lose the row for any summary that lacks an answer to one or more questions.
2) Break into columns with an IF block: See this SO question (specifically the accepted answer) for an illustration: Transpose mysql query rows into columns

MYSQL php couple of tables not working

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.

Categories