Inserting Data to a Table Retrieved from Two Merged Tables - php

I have two courses. In each course there are several assignments. A student can follow both courses.
I have the following tables:courses,student_courses,course1
My courses table has st_index,assignmnet_no,marks,course_no as the fields
and student_courses table has st_index,course1,course2 where 1is inserted if the student follows course1 or course2 .
Table course1 has Student_Index, Assignment1, Assignment2,Assignment3 as fields.
I have inserted my data into tables courses,student_courses. By retrieving data from these I want to come up with course1 table.course1
should look as follows:
Here's my code:
if($_SESSION['user']['course']=="Course1"){
$result=mysql_query("SELECT student_index FROM student_courses WHERE course1=1");
while($index=mysql_fetch_array($result)){
echo $index[0];
echo"<br>";
$result2=mysql_query("SELECT * FROM courses WHERE course_no='Course1' AND st_index='$index[0]'");
while($i2=mysql_fetch_array($result2)){
$ass_no=$i2['assignment_no'];
if($ass_no=='1'){
echo $index[0];
$result3=mysql_query("INSERT INTO course1(Student_Index,Assignment1) VALUES('$index[0]','$i2[marks]')");
}
if($ass_no=='2'){
echo $index[0];
$result4=mysql_query("INSERT INTO course1(Assignment2) VALUES('$i2[marks]')");
}
if($ass_no=='3'){
$result5=mysql_query("INSERT INTO course1(Assignment3) VALUES('$i2[marks]')");
}
}
}
}
?>
The problem is for course1 only the first student_index assignment values gets inserted. In there also for the same student_index the values gets inserted into two separate rows. What I am trying to do is when we consider a row in course1, which is identified by student_index that row should have all the assignment marks of that student. How can I achieve this?
That is say I have two records that match the conditions for the table course1 as 945,568.
In the course1 it only gets inserted records for 965 and it also looks like below. . The two rows should be one, under same index_no
In order to check what is going wrong inside first while loop I used echo $index[0] . It prints 945,568 both. But in the if statements inside the other while loop only 945 gets printed. That is when the loop is run for the second time I think the line $result2=mysql_query("SELECT * FROM courses WHERE course_no='Course1' AND st_index='$index[0]'"); doesn't get executed.

The problem is that in SQL, INSERT always adds a new row. You've inserted a row for each mark, but only provided a Student_Index for one of them (thus the empty indexes on subsequent rows). What you want is the UPDATE command.
So let's just use INSERT once to create a row for each student, just before the inner WHILE:
INSERT INTO course1(Student_Index) VALUES('$index[0]')
and then fill the fields by replacing your INSERT statements with (e.g. for assignment 1):
UPDATE course1 SET assignment1 = '$i2[marks]' WHERE Student_Index = '$index[0]'
Alternatively, you can accomplish this in SQL alone with the following:
CREATE TABLE course1
SELECT s1.st_index,
a1.marks AS Assignment1,
a2.marks AS Assignment2,
a3.marks AS Assignment3
FROM courses a1, courses a2, course a3
WHERE a1.course_no = 1
AND a2.course_no = 1
AND a3.course_no = 1
AND a1.assignment_no = 1
AND a2.assignment_no = 2
AND a3.assignment_no = 3
AND a1.st_index = a2.st_index
AND a1.st_index = a3.st_index;
We've joined the course table three times to select out the three rows where the three marks reside for with course_no=1 and constrained them to be the same student in all three rows. This will return one row for each student. Also, With this solution there is no need for a reference to the student_courses table at all since you can infer the enrollment of a student in a course by the presence of marks in the course table.

Related

SQL Join statement into a single field in a HTML Table using PHP

so i'm creating a schedule system and i'm trying to display the information for the appointment and also, userID's for those who have booked a possition.
I have created a table for Students, Classes and ClassAssosication where the ClassID and UserID are PK And FK from the other tables. I have created a join statement =
SELECT classes.ClassName, students.UserID
FROM classassociation
JOIN students
ON classassociation.UserID = Students.UserID
JOIN classes
ON classassociation.ClassID = classes.ClassID
WHERE classassociation.ClassID = 1;
Where it retrieves the UserID and ClassName for those who have booked a place for Class with the ID = 1 .
I am trying to create a PHP/HTML table where in a field for example, Monday 9AM, i can print out the join statement, for example, Methodology, 1 ,2 (user Id's).
Day | 9AM | 10AM
Monday | Methodology, 1,2 |
Tuesday | |
I need this done for multiple classes but trying to attempt one for now. I am unsure of how to do this, so any help will be appreciated. Thank you.
Your query as written will return a row for each ClassName/UserId pair - if there are two people in the methodology class there will be two rows in your query result.
You can choose to combine them in a loop in php, or you can alter your query to group things together. If you think of it as "I want to group all the UserIds for a given classname", it suggest how to use the GROUP BY clause in your SQL:
SELECT classes.ClassName, students.UserID
FROM classassociation
JOIN students
ON classassociation.UserID = Students.UserID
JOIN classes
ON classassociation.ClassID = classes.ClassID
WHERE classassociation.ClassID = 1
GROUP BY ClassName;
Now there will be one row for each ClassName, but you still need to tell MYSQL how to handle the multiple UserIds for each row. In your case, you want to have the UserIds joined together in a comma-separated list. Happily, there's a special section in the manual just for the functions you use with GROUP BY. In this case GROUP_CONCAT gives the desired result:
SELECT classes.ClassName, GROUP_CONCAT(students.UserID SEPARATOR ',') AS UersIds
FROM classassociation
JOIN students
ON classassociation.UserID = Students.UserID
JOIN classes
ON classassociation.ClassID = classes.ClassID
WHERE classassociation.ClassID = 1
GROUP BY ClassName;
Now you will get a result set with one row for each ClassName, with two columns:
ClassName | UserIds
---------------------
Methodology | 1,2
Then you can write a simple php loop to take each row in the query and generate a table row in your html.
If you look at the manual for GROUP_CONCAT, you can see that you can also set the order that the userIds are grouped in, which might be useful.
The php loop is pretty simple once you have your query results; you just need to create a table and then add a row for each result:
/*assume your mysql query has returned an array of objects named $result */
// in your html document, create your table with its header
print '<table><thead><tr><th>Class Name</th><th>UserIds</th></tr></thead>';
print '<tbody>';
// now loop through your query results and put stuff into the table
// of course you can monkey around with the table format and what goes in each cell
foreach($result as $row) {
print '<tr><td>'.$row->ClassName.'</td><td>'.$row->UserIds.'</td></tr>';
}
print '</tbody></table>';
That's a very simple example, but hopefully demystifies the process somewhat.
Your particular case looks like the query is actually to get the contents of one cell in your table; you can either do a much grander query that groups by time and day of week, or you can do little queries and store the results in nested arrays that model how you want your table to look. The html output is structurally the same, but you would have a php loop for each table cell.
To have table with each cell showing the result of a separate query, consider something like the following pseudocode:
$days = array('Monday', 'Tuesday',...'Friday');
$times = array('9', '10'...);
$weekResults = array();
foreach($days as $day) {
$weekResults[$day] = array();
foreach($times as $time) {
$weekResults[$day][$time] = doQuery($day, $time);
}
}
// now you have nested arrays with a result set for each table cell.
// Rendering the table, you just use the same loops:
renderTableHeader(); // all the <table><thead> stuff
foreach($weekResults as $day) {
print '<tr>'
foreach($day as $time) {
print '<td>';
// output the data from your query like above
// if the formatting is complex, you can even put another table inside the <td>.
print '</td>';
}
print '</tr>';
}
renderTableFooter(); // close tbody and table tags
Hope that helps!

select multiple values from one condition (PHP/MySQL)

I have a table which holds details of exams taken. Each exam entered into this table is entered as a pair of people i.e. two people per exam performed so you have per exam, two people. Each person has their own unique id for each exam taken but each pair has a value called partner_id which is the same for them both.
What I am trying to do is extract the partner_id values from that table in order to then be able to use those values to find the partners of a said person and show/echo onto the page the exam result details of every partner that person has had exam with.
What I have tried so far is:
$partner_ider = mysql_query("SELECT partner_id as value1 from exam WHERE Student_email='eating#gnomes.com'");
$row1 = mysql_fetch_array($partner_ider);
while($row1 = mysql_fetch_array($partner_ider))
{
echo $row1['value1'];
}
And this:
$result = mysql_query("SELECT * from exam WHERE Student_email='beating#dead.com'");
$row = mysql_fetch_array($result);
while ($row = mysql_fetch_array($result))
{
echo $row['partner_id'];
}
The result these would give is 2 for that email of which has two entries in the exam table, what I was looking for was 1, 2 which are the values of the two partner_ids for this email's exam records. When I change the email to someone else who only has one, it returns nothing.
What I would be looking to do with the result of 1, 2 is to use those values to select all other people except the original person(eating#gnomes.com) and show their details from out of that table.
What I'm asking for is how would I go about doing the above as I haven't done something like this before?
In both code snippets, you have at line 2 a mysql_fetch_array() which should not be there.
It fetches a row, puts it into $row1 and increments the internal pointer.
When you call mysql_fetch_array() in your while, it fetches the second record then the third etc. until all the rows have been processed.
You should, in both examples, remove the second line and try again.
$partner_ider = mysql_query("SELECT partner_id as value1 from exam WHERE Student_email='eating#gnomes.com'");
//$row1 = mysql_fetch_array($partner_ider);
while($row1 = mysql_fetch_array($partner_ider))
{
echo $row1['value1'];
}
If your table structure is the following :
id
student_id
student_name
student_email
student_whatever
partner_id
The SQL query would look like
SELECT Student_email FROM exam WHERE partner_id IN (SELECT partner_id FROM exam WHERE student_Email = 'eating#gnomes.com') AND Student_email <> 'eating#gnomes.com';
But you should really split up your table. You have two entities (a student and an exam) and a joining table.
Student
id
name
email
Exam
id
name
(other exam data)
StudentGroup
exam_id
student_id
group

PHP/ MYSQL Inserting Data Into Multiple Tables

I am trying to add data into 3 table using PHP, atm I can only view the results of the tables that are joined .
RESULTS QUERY
$sql = mysql_query("SELECT PART_ID, PART_DESC, SERIAL_NUM, PART.RACK_NUM, PART.PART_TYPE_ID, PART_TYPE_DESC, LOCATION
FROM PART
INNER JOIN PART_TYPE ON PART.PART_TYPE_ID = PART_TYPE.PART_TYPE_ID
INNER JOIN RACK ON RACK.RACK_NUM = PART.RACK_NUM
This will get all the rows from the PART table, and for each of the rows we find, match that row to a row in the PART_TYPE table (the condition being that they have the same PART_TYPE_ID). If no match between the PART and PART_TYPE tables can be found for a given row in the PART table, that row will not be included in the result.
My Insert Query This is where im having trouble
How do I add the data to the PART_ID, PART_TYPE and RACK tables?
<?php
// Parse the form data and add inventory item to the system
if (isset($_POST['PART_ID'])) {
$id = mysql_real_escape_string($_POST['PART_ID']);
$PART_DESC = mysql_real_escape_string($_POST['PART_DESC']);
$SERIAL_NUM = mysql_real_escape_string($_POST['SERIAL_NUM']);
$RACK_NUM = mysql_real_escape_string($_POST['RACK_NUM']);
$PART_TYPE_ID = mysql_real_escape_string($_POST['PART_TYPE_ID']);
$LOCATION = mysql_real_escape_string($_POST['LOCATION']);
$PART_TYPE_DESC = mysql_real_escape_string($_POST['PART_TYPE_DESC']);
// See if that product name is an identical match to another product in the system
$sql = mysql_query("SELECT PART_ID FROM PART WHERE PART_ID='$id' LIMIT 1");
$productMatch = mysql_num_rows($sql); // count the output amount
if ($productMatch > 0) {
echo 'Sorry you tried to place a duplicate "Product Name" into the system, click here';
exit();
}
// Add this product into the database now
**$sql = mysql_query("INSERT INTO PART (PART_ID, PART_DESC, SERIAL_NUM, RACK_NUM, PART_TYPE_ID)
VALUES('$id','$PART_DESC','$SERIAL_NUM','$RACK_NUM','$PART_TYPE_ID')") or die (mysql_error());**
header("location: inventory_list.php");
exit();
}
?>
Micheal if I understood your problem you just need to do 2 other SQL INSERT to add data in the other table
$sql = mysql_query("INSERT INTO PART (PART_ID, PART_DESC, SERIAL_NUM, RACK_NUM, PART_TYPE_ID)
VALUES('$id','$PART_DESC','$SERIAL_NUM','$RACK_NUM','$PART_TYPE_ID')") or die (mysql_error());
$currentID = mysql_inserted_id();
$sql2 = mysql_query("INSERT INTO PART_TYPE [..]");
$sql3 = mysql_query("INSERT INTO RACK [..]");
You can use $currentID if you need the ID of the last record inersted into PART
But still I strongly suggest you to learn PDO http://php.net/pdo for sql
your table management is wrong, you never use arrows just to show that you are joining it with that table from this table, but rather from the key in first table to foreign key in the second table, that's what i would start from, maybe a better idea would be to join them using JOIN look up in google how joins are working, that may be the cause...
I agree with #yes123, that is the correct way to insert into tables, if you have a program called heidisql then use it, because there is a window to run your queries... that way to test if it is properly written also use mysql_error.
Debug, debug, and one more time debug your code.
Your tables are not correctly designed.
Try this table structures .
In your base table Part. -
The columns in this should be:
Part_id
part_desc
serial_num
The part_type should have following columns:
part_type_id
part_type_desc
part_id -> foreign key to the parent table
The rack table should be:
Rack_num
location
part_id -> foreign key to the parent table.
So your select query to get all the part related information would be:
$sql="select * from part join part_type pt on tp.part_id=part.part_id join Rack_num rn on rn.part_id=part.part_id";
With this structure the data remains normalized. And is flexible, so if the parts are on multiple racks you just go to the rack table and add and new rack number and the part id.

What's the most efficient way to pull the data from mysql so that it is formatted as follows:

I have a table that has patient information (name, dob, ssn, etc.) and a table that has lists of medications that they take. (aspirin, claritin, etc.) The tables are related by a unique id from the patient table. So, it's easy enough to pull all of Mary Smith's medications.
But, what I need to do is to show a paginated list of patients that shows their name, other stuff from the patient table and has a column with a line-separated list of their medications. Roughly, this:
If I do a simple left join, I get 3 repeated rows of Mary Smith with one medication per row.
The patient table can have thousands of records, so I don't want to do a query to get all the patients and then loop through and get their meds. And, because it's paginated based on patient, I can't figure out how to get the correct number of patients for the page, along with all their medications.
(The patients/medications thing is just a rough example of the data; so please don't suggest restructuring how the data is stored.)
GROUP_CONCAT to the rescue!
SELECT patients.first_name, patients.last_name, GROUP_CONCAT(prescriptions.medication SEPARATOR ", ") AS meds FROM patients LEFT JOIN prescriptions ON prescriptions.patient_id = patients.id GROUP BY patients.id;
You've got a few choices.
rowspan clauses with one drug per cell per user. You'd need to run two SQL queries to precalculate how big each user's span would have to be, or suck the query results into PHP and do the counting there.
Simple state machine - start a new row each time the user changes, then just keep adding more drug names seperated with <br /> while the user's name stays constant.
The second one's probably easiest:
$previous_name = null;
$first = true;
echo "<table";
while($row = mysql_fetch_assoc($results)) {
if ($row['name'] <> $previous_name) {
if (!$first) {
echo "</td></tr>"; // end previous row, if it's not the first row we've output
$first = false;
}
echo "<tr><td>$row[name]</td><td>"
$previous_name = $row['name'];
}
echo "$row['drug']<br />";
}
echo "</td></tr></table>";
I think what you are looking for is referred to a 'concation of subquery'.
Check http://forums.mysql.com/read.php?20,157425,157796#msg-157796 and http://mysql.bigresource.com/SELECT-CONCAT-Subquery-S5cIpzqO.html

Move Multiple Tables into One, with Addition of Extra Field Value

I have 31 separate tables (actually I have 365, but lets keep this simple) in a MySQL database, each containing data for a given day. The tables are (badly) named based on the day.
Example:
island01Aug07
island02Aug07
island03Aug07
island04Aug07
...
island31Aug07
I would like to combine all the tables into one master table:
island_08
It would be simple to use INSERT INTO but my problem is that the tables do not have a column to denote the day. It would have to be added into the destination table, and then I would need to populate that when moving/copying the tables over.
Suggestions, advice and solutions welcome.
CREATE TABLE island_08 (mydate DATE NOT NULL, field1 …)
INSERT
INTO island_08 (mydate, field1, field2)
SELECT '2007-07-01', field1, field2
FROM island01Aug07
UNION ALL
SELECT '2007-07-02', field1, field2
FROM island02Aug07
UNION ALL
…
As alternative option you can list all tables in to array like table_name=>mysql_date,
after that loop through and copy data from one table and insert in to another. After data was transferred successfully you can remove the table.
Here is example of getting list of tables and extracting date from it:
$prefix = 'island';
$lenght = strlen($prefix);
$result = $this->query("SHOW TABLES LIKE '{$prefix}%'");
$arrayDates = array();
if($db->num_rows($result))
{
while($v = $db->fetch_array($result))
{
$mysql_table = current($v);
$arrayDates[$mysql_table] = date('d-m-Y',strtotime(substr($mysql_table,0,$lenght)));
}
}
//Now you can walk through your array and copy data from one table tyo another and append you mysql value

Categories