I don't know how to explain this but what I want to do is kind of merge two database field together and output the new field using php. For example:
Answer Table:
AnswerId: 10
AnswerContent: Manchester
AnswerId :11
AnswerContent: Leeds
AnswerId:12
AnswerContent:Birmingham
StudentAnswer Table:
Student: Bob
StudentAnswer:10
Student: Jim
StudentAnswer:11
What I want to do is that when I run the query which I will show below with my php coding, for the StudentAnswer field I want it to display the name of the answer rather than the answer id. How can this be achieved?
Below is the code:
<?php
if (isset($_POST['submit'])) {
$query = "
SELECT * FROM Question q
INNER JOIN StudentAnswer sa ON q.QuestionId = sa.QuestionId
JOIN Answer a ON sa.QuestionId = a.QuestionId
WHERE
('".mysql_real_escape_string($sessionid)."' = '' OR q.SessionId = '".mysql_real_escape_string($sessionid)."')
AND
('".mysql_real_escape_string($questionno)."' = '' OR q.QuestionNo = '".mysql_real_escape_string($questionno)."')
AND
('".mysql_real_escape_string($studentid)."' = '' OR sa.StudentId = '".mysql_real_escape_string($studentid)."')
AND(CorrectAnswer = '1')
ORDER BY $orderfield ASC";
$num = mysql_num_rows($result = mysql_query($query));
mysql_close();
?>
<p>
Your Search:
<strong>Session ID:</strong> <?php echo (empty($sessionid)) ? "'All Sessions'" : "'$sessionid'"; ?>,
<strong>Question Number:</strong> <?php echo (empty($questionno)) ? "'All Questions'" : "'$questionno'"; ?>,
<strong>Student Username:</strong> <?php echo (empty($studentid)) ? "'All Students'" : "'$studentid'"; ?>,
<strong>Order Results By:</strong> '<?php echo $ordername; ?>'
</p>
<p>Number of Records Shown in Result of the Search: <strong><?php echo $num ?></strong></p>
<table border='1'>
<tr>
<th>Session ID</th>
<th>Question Number</th>
<th>Question</th>
<th>Correct Answer</th>
<th>StudentAnswer</th>
<th>Correct Answer Weight</th>
<th>Student Answer Weight</th>
<th>Student ID</th>
</tr>
<?php
while ($row = mysql_fetch_array($result)) {
echo "
<tr>
<td>{$row['SessionId']}</td>
<td>{$row['QuestionNo']}</td>
<td>{$row['QuestionContent']}</td>
<td>{$row['AnswerContent']}</td>
<td>{$row['StudentAnswer']}</td>
<td>{$row['Weight%']}</td>
<td></td>
<td>{$row['StudentId']}</td>
</tr>";
}
?>
</table>
<?php
}
?>
Thank You
I think you could use:
SELECT q.*, a.AnswerContent FROM Question q
INNER JOIN StudentAnswer sa ON q.QuestionId = sa.QuestionId
INNER JOIN Answer a ON sa.QuestionId = a.QuestionId
WHERE ....
I mean, you should return the text for the answer (you're still joining tables, so you do have that field).
Related
My code join 4 table using INNER JOIN. I can't customize loop while using inner join. How to control while clause so unwanted loop wouldn't happen.
My code output (student and school name is looping in every subject field)
I want to display like this where student and school loops at once.
MY PHP Code
<table id="customers">
<?php
$query=$con->prepare("SELECT subjectcomb.subjectid, subjectcomb.schoolid, student.student, school.school, subject.name
FROM ((( subjectcomb
INNER JOIN school ON subjectcomb.schoolid=school.id)
INNER JOIN student ON subjectcomb.schoolid=student.schoolID)
INNER JOIN subject ON subjectcomb.subjectid=subject.id)");
$query->execute();
while ($row = $query->fetch(PDO::FETCH_ASSOC)){?>
<tr>
<td>
<?php echo $row['school']."->".$row['student']?>
</td>
</tr>
<tr>
<td>
<?php echo $row['name']?>
<input type="text" name="mark"></input>
</td>
</tr>
<?php } ?>
</table>
Try adding an ORDER BY to your query:
$query=$con->prepare("SELECT subjectcomb.subjectid, subjectcomb.schoolid, student.student, school.school, subject.name
FROM ((( subjectcomb
INNER JOIN school ON subjectcomb.schoolid=school.id)
INNER JOIN student ON subjectcomb.schoolid=student.schoolID)
INNER JOIN subject ON subjectcomb.subjectid=subject.id)
ORDER BY school.school, student.student");
then in the while loop use this check:
<?php
$last_student = ""
while ($row = $query->fetch(PDO::FETCH_ASSOC)){
if ($last_student != $row['student']) {
?>
<tr>
<td>
<?php echo $row['school']."->".$row['student']?>
</td>
</tr>
<?php } ?>
<tr>
<td>
<?php echo $row['name']?>
<input type="text" name="mark"></input>
</td>
</tr>
<?php $last_student = $row['student'] } ?>
I think what Phil meant was something like the following. You keep track of the previous school and student. If the current school and student are the same as the previous, you skip printing the school/student row, but if they not the same, you print them and also update the previous school's and previous student's values.
$prev_school = '';
$prev_student = '';
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
if ($row['school'] != $prev_school && $row['student'] != $prev_student) { ?>
<tr>
<td>
<?php echo $row['school']."->".$row['student'] ?>
</td>
</tr>
<?php
$prev_school = $row['school'];
$prev_student = $row['student'];
}
?>
<tr>
<td>
<?php echo $row['name']?>
<input type="text" name="mark"></input>
</td>
</tr>
<?php
}
I have question table and subject table and question table contain subject wise questions for online examination.
I need to fetch subject wise questions with subject name as header and show all the questions in subject wise serial number such as example: Maths: Q1, Q2, Q3
English: Q1, Q2, Q3 and so on.
How to achieve it in php and mysql. The question table and subject table are given below.
Question sample data are given below
<?php
require_once 'config.php';
//$con = mysqli_connect("localhost","root","","database_name");
$query1 = "SELECT q.q_id,q.setq_no, q.qtext_eng, s.sub_id, s.sub_name
FROM question q
INNER JOIN subject s ON s.sub_id = q.sub_id
INNER JOIN questionset qs ON qs.qset_id = q.qset_id
WHERE qs.qset_id =2 ORDER BY s.sub_id";
?>
<table class="table table-bordered">
<thead>
<tr>
<th>Q.No</th>
<th>Q Set number</th>
<th>Q text eng</th>
</tr>
<?php
$result1 = mysqli_query($link,$query1);
while($row1 = mysqli_fetch_array($result1))
{
$subID = $row1['sub_id'];
$subName = $row1['sub_name'];
?>
<h2><?php echo "$subName" ?></h2>
<?php
error_reporting(0);
$sno++;
$qSet = $row1['setq_no'];
$qEng = $row1['qtext_eng'];
?>
<tr>
<td><?php echo $sno; ?></td>
<td><?php echo $qSet; ?></td>
<td><?php echo $qEng; ?></td>
</tr>
</tbody>
</table>
<?php
}
?>
I am including some of your columns from question table here , you can add the rest same way
<?php
$con = mysqli_connect("localhost","root","","database_name");
$query1 = "SELECT q.q_id,q.setq_no, q.qtext_eng, s.sub_id, s.sub_name
FROM question q
INNER JOIN subject s ON s.sub_id = q.sub_id
INNER JOIN questionset qs ON qs.qset_id = q.qset_id
WHERE qs.qset_id =2 ORDER BY s.sub_id";
$presubID = 0;
<table class="table table-bordered">
while($row1 = mysqli_fetch_array($result1))
{
$subID = $row1['sub_id'];
if($subID != $presubID){
$subName = $row1['sub_name'];
<h2><?php echo "$subName" ?></h2>
$sno=0;
<thead>
<tr>
<th>Q.No</th>
<th>Q Set</th>
<th>Q text eng</th>
</tr>
</thead>
}
$presubID = $subID;
$sno++;
$qSet = $row1['setq_no'];
$qEng = $row1['qtext_eng'];
<tr>
<td><?php echo $sno; ?></td>
<td><?php echo $qSet; ?></td>
<td><?php echo $qEng; ?></td>
</tr>
<?php
}
?>
</table>
I have two Table ownership_profile and socity_unit.
Query For table1: select * from ownership_profile where SID='$id'
Query For Table2: select * from socity_unit where socity_id='$sid'
I have to join with one query, but i don't have idea how to do it.
This is my Php code but gives error:
<!-----------------Table For User Names-------------------------------------->
<table border="1" align="center">
<tr>
<th>Unit No</th>
<th>Member Name</th>
<th>Wing</th>
<th>Unit</th>
</tr>
<?php
if(isset($_GET['submit']))
{
$sql = "select * from ownership_profile o inner join society_unit s on o.sid = s.society_id where o.sid = '$sid' ";
$result = mysql_query($sql);
$i=1;
while($row=mysql_fetch_array($result)){
?>
<?php
$name = $row['NAME'];
$unitid = $row['UNIT_ID'];
$sid = $row['SID'];
$wings = $row['wings'];
$unit_no = $row['unit_no'];
{
?>
<!--User Submit Result-->
<tr>
<td><?php echo $unitid; ?></td>
<td><?php echo $name; ?></td>
<td><?php echo $wings; ?></td>
<td><?php echo $unit_no; ?></td>
</tr>
<?php }?>
<?php
//echo "<br>";
$i++;
}
}
?>
inner join is what you want.
select *
from ownership_profile o
inner join society_unit s
on o.sid = s.society_id
where o.sid = '$sid'
This assumes that 'sid' and 'society_id' are the relationship identifiers.
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name;
select * from ownership_profile o inner join socity_unit s on o.SID = s.socity_id where o.SID = '$SOCIETY_ID'
This query working fine but...... its generate dublicate entry from table
I am trying to create dynamic html table but the problem is that it is not displaying any data in the table. I know the query is correct because I tested the query in sql and it outputs the data. The problem I have I am guessing is the dynamic html table itself. Below is the code:
JavaScript/JQuery:
//javascript below will perform calculation between adding numbers between text inputs per each question
//answer for each calculation per question is stored under "Total Marks Remaining" Column
/*If a question only has one answer, then the text input under the "Marks Per Answer" column becomes
read only and displays the same number as the total marks under the "Total Marks Remaining" column
for that question*/
$(function() {
//alert("here");
var questions = $('#markstbl td[class*="_ans"]').length-1;
//disable single entry
for (var i=0;i<=questions;i++){
if($("[class*=q"+i+"_mark]").length ==1){
var t_marks = $("[class*=q"+i+"_ans]").html();
//alert(t_marks);
$("[class*=q"+i+"_mark]").val(t_marks).attr("disabled","disabled");
//$("[class*=q"+i+"_mark]").attr("disabled","disabled");
}
}
//find each question set and add listeners
for (var i=0;i<=questions;i++){
$('input[class*="q'+i+'"]').keyup(function(){
var cl = $(this).attr('class').split(" ")[1]
var questionno = cl.substring(cl.indexOf('q')+1,cl.indexOf('_'));
var tot_marks = $(".q"+questionno+"_ans_org").val();
//alert(tot_marks);
var ans_t=0;
$("[class*=q"+questionno+"_mark]").each(function(){
var num = (isNaN(parseInt($(this).val())))?0:parseInt($(this).val());
ans_t+=parseInt(num);
});
ans_t=tot_marks-ans_t;
//alert(ans_t);
//var fixedno = tot_marks;
var ans = (parseInt(ans_t)<0)?tot_marks:ans_t;
$(".q"+questionno+"_ans").val(ans);
$(".q"+questionno+"_ans_text").html(ans);
});
}
});
</script>
PHP:
<?php
if (isset($_POST['id'])) {
$_SESSION['id'] = $_POST['id'];
}
$assessment = $_SESSION['id'];
include('connect.php');
$query = "SELECT q.SessionId, s.SessionName, q.QuestionId, q.QuestionContent, an.Answer, q.QuestionMarks
FROM Session s
INNER JOIN Question q ON s.SessionId = q.SessionId
JOIN Answer an ON q.QuestionId = an.QuestionId AND an.SessionId = q.SessionId
WHERE s.SessionName = ?
ORDER BY q.QuestionId, an.Answer";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("s", $assessment);
// execute query
$stmt->execute();
// This will hold the search results
$searchQuestionId = array();
$searchQuestionContent = array();
$searchAnswer = array();
$searchMarks = array();
// Fetch the results into an array
// get result and assign variables (prefix with db)
$stmt->bind_result($dbSessionId, $dbSessionName, $dbQuestionId, $dbQuestionContent, $dbAnswer, $dbQuestionMarks);
while ($stmt->fetch()) {
$searchQuestionId[] = $dbQuestionId;
$searchQuestionContent[] = $dbQuestionContent;
$searchAnswer[] = $dbAnswer;
$searchMarks[] = $dbQuestionMarks;
}?>
HTML:
<form id="Marks" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post">
<table border='1' id='markstbl'>
<thead>
<tr>
<th class='questionth'>Question No.</th>
<th class='questionth'>Question</th>
<th class='answerth'>Answer</th>
<th class='answermarksth'>Marks per Answer</th>
<th class='noofmarksth'>Total Marks</th>
</tr>
</thead>
<?php
$row_span = array_count_values($searchQuestionId);
$prev_ques = '';
foreach($searchQuestionId as $key=>$questionId){?>
<tbody>
<tr class="questiontd">
<?php
if($questionId != $prev_ques){?>
<td class="questionnumtd" name="numQuestion" rowspan="<?=$row_span[$questionId]?>"><?=$questionId?> <input type="hidden" name="q<?=$questionId?>_ans_org" class="q<?=$questionId?>_ans_org" value="<?=$searchMarks[$key]?>"><input type="hidden" name="q<?=$questionId?>_ans" class="q<?=$questionId?>_ans" value="<?=$searchMarks[$key]?>"></td>
<td class="questioncontenttd" rowspan="<?=$row_span[$questionId]?>"><?=$searchQuestionContent[$key]?> </td>
<?php
}else{?>
<td class="questionnumtd" name="numQuestion" ></td>
<td class="questioncontenttd" ></td>
<?php
}?>
<td class="answertd" name="answers[]"><?=$searchAnswer[$key]?></td>
<td class="answermarkstd">
<input class="individualMarks q<?=$questionId?>_mark_0" q_group="1" name="answerMarks[]" id="individualtext" type="text" />
</td>
<?php
if($questionId != $prev_ques){?>
<td class="noofmarkstd q<?=$questionId?>_ans_text" q_group="1" rowspan="<?=$row_span[$questionId]?>"><?=$searchMarks[$key]?></td>
<?php
}else{?>
<td class="noofmarkstd" q_group="1"></td>
<?php
}?>
</tr>
<?php
$prev_ques = $questionId;
}?>
</tbody>
</table>
</form>
Below is the screenshot of what it is displaying:
Below is what the table should display (The Marks per Answer Column contains text inputs for each row)
Below is database design so you can see where the data is coming from:
Session Table: (Where the exam details is stored)
SessionId SessionName
1 AAA
Question Table: (Where questions for each exams are stored)
SessionId QuestionId QuestionContent Total Marks
1 1 Name three features in a ROM 5
1 2 Here is a single answer 5
Answer Table: (Stores answers for each question in each exam)
AnswerId(auto) SessionId QuestionId Answer
1 1 1 A
2 1 1 B
3 1 1 D
4 1 2 True
Individual_Answer Table: (Stores each individual mark for each individual answer)
AnswerId AnswerMarks
1 2
2 2
3 1
4 5
UPDATE:
Looking at my html code, why is it displaying the table like this below:
Check for missing php open tag <?php before include('connect.php');
Also avoid short tags like <?= and replace them with <?php echo
place <tbody> outside the foreach loop
foreach($searchQuestionId as $key=>$questionId){
?>
<tbody>
to
</thead>
<tbody>
....
....
foreach($searchQuestionId as $key=>$questionId){
?>
Unless there is some code that is not being displayed here, perhaps it's as simple as the $assessment variable not being set, so nothing is being sent to the query?
Also, to confirm that you are actually getting the results back AND binding them OK, I'd be doing a var_dump on the arrays like searchQuestionContent to make sure they have the content you expect in them, if not you know your problem is in the query / binding data. If they do have the content you expect, then you know the problem lies in the table output.
I have this query below:
SELECT q.SessionId, s.SessionName, q.QuestionId, q.QuestionContent, GROUP_CONCAT(DISTINCT Answer ORDER BY Answer SEPARATOR '') AS Answer, q.QuestionMarks
FROM Session s
INNER JOIN Question q ON s.SessionId = q.SessionId
JOIN Answer an ON q.QuestionId = an.QuestionId
AND an.SessionId = q.SessionId
WHERE s.SessionName = "GHWSW1" AND q.QuestionId = 1
GROUP BY an.SessionId, an.QuestionId
ORDER BY q.QuestionId, an.Answer
The query above outputs this result below:
SessionId SessionName QuestionId QuestionContent Answer QuestionMarks
1 GHWSW1 1 Here are 2 answers BD 5
So I included the query in the code below and set up a html table:
$assessment = "GHWSW1";
$number = 1;
$query = "SELECT q.SessionId, s.SessionName, q.QuestionId, q.QuestionContent,
GROUP_CONCAT(DISTINCT Answer ORDER BY Answer SEPARATOR '') AS Answer, q.QuestionMarks
FROM Session s
INNER JOIN Question q ON s.SessionId = q.SessionId
JOIN Answer an ON q.QuestionId = an.QuestionId AND an.SessionId = q.SessionId
WHERE s.SessionName = ? AND q.QuestionId = ?
GROUP BY an.SessionId, an.QuestionId
ORDER BY q.QuestionId, an.Answer
";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("si", $assessment, $number);
// execute query
$stmt->execute();
// This will hold the search results
$searchQuestionId = array();
$searchQuestionContent = array();
$searchAnswer = array();
$searchMarks = array();
// Fetch the results into an array
// get result and assign variables (prefix with db)
$stmt->bind_result($dbSessionId, $dbSessionName, $dbQuestionId, $dbQuestionContent, $dbAnswer, $dbQuestionMarks);
while ($stmt->fetch()) {
$searchQuestionId[] = $dbQuestionId;
$searchQuestionContent[] = $dbQuestionContent;
$searchAnswer[] = $dbAnswer;
$searchMarks[] = $dbQuestionMarks;
}
?>
</head>
<body>
<form id="QandA" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post">
<?php
echo "<table border='1' id='markstbl'>
<tr>
<th class='questionth'>Question No.</th>
<th class='questionth'>Question</th>
<th class='answerth'>Answer</th>
<th class='noofmarksth'>Total Marks</th>
</tr>\n";
foreach ($searchQuestionContent as $key=>$question) {
echo '<tr class="questiontd">'.PHP_EOL;
echo '<td class="optiontypetd">'.htmlspecialchars($searchQuestionId[$key]).'</td>' . PHP_EOL;
echo '<td>'.htmlspecialchars($question).'</td>' . PHP_EOL;
echo '<td class="answertd">'.htmlspecialchars($searchAnswer[$key]).'</td>' ;
echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
}
echo "</table>" . PHP_EOL;
?>
So the HTML table displays it like this:
QuestionId QuestionContent Answer QuestionMarks
1 Here are 2 answers BD 5
But I want it like this in the html table:
QuestionId QuestionContent Answer QuestionMarks
1 Here are 2 answers B 5
D
The second Answer D should be in a seperate row and the other rows should have a rowspan. But how can this be achieved?
Session Table:
SessionId (auto) SessionName
1 AAA
Question Table:
SessionId QuestionId (auto) QuestionContent
1 1 What is 2+2?
Answer Table:
AnswerId (auto) SessionId QuestionId Answer
1 1 1 B
2 1 1 D
try this
foreach ($searchQuestionContent as $key=>$question) {
echo '<tr class="questiontd">'.PHP_EOL;
echo '<td class="optiontypetd">'.htmlspecialchars($searchQuestionId[$key]).'</td>' . PHP_EOL;
echo '<td>'.htmlspecialchars($question).'</td>' . PHP_EOL;
echo '<td class="answertd">'.htmlspecialchars($searchAnswer[$key]).'</td>' ;
echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
echo '</tr>';
}
you forget to close the tr tag
Remove the GROUP BY clause and add make the foreach loop look like this:
echo "<table border='1' id='markstbl'>
<tr>
<th class='questionth'>Question No.</th>
<th class='questionth'>Question</th>
<th class='answerth'>Answer</th>
<th class='answermarksth'>Marks per Answer</th>
<th class='noofmarksth'>Total Marks</th>
</tr>\n";
$previous_question_id = null;
foreach ($searchQuestionContent as $key=>$question) {
if ($previous_question_id == $searchQuestionId[$key]) {
$searchQuestionId[$key] = '';
$question = '';
$searchMarks[$key] = '';
}else{
$previous_question_id = $searchQuestionId[$key];
}
echo '<tr class="questiontd">'.PHP_EOL;
echo '<td class="optiontypetd">'.htmlspecialchars($searchQuestionId[$key]).'</td>' . PHP_EOL;
echo '<td>'.htmlspecialchars($question).'</td>' . PHP_EOL;
echo '<td class="answertd">';
echo $searchAnswer[$key];
echo '</td>' ;
echo '<td class="answermarkstd"><input class="individualMarks" name="answerMarks[]" id="individualtext" type="text" "/></td>' . PHP_EOL;
echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
}
echo '</tr>';
echo "</table>" . PHP_EOL;