Resolving table(mysql, php) - php

I got 3 table, called class , student and class_student(resolving table) . This is due to many to many relationship between class and student. A student can have many class and a class can have many student. The fields inside class is(class_id, class_start_time and class_end_time) , student(student_id, student_name, student_age) , class_student(student_id , class_id). My question would be : Inside a class, it includes student , how do I add student into the class table ? Or should I make use of the resolving table? My understanding of resolving table is weak and I'm not sure what's the purpose of it.
Thank you all for your answer !
What about when I add a new record to class student table , do I add a new record to class table as well?

The most common way to resolve a many to many relationship is via a seperate relation table (as Barmar noted).
In your case that table could have these fields:
table class_students
--------------------
id // an unique id of that relationship;
// could be ommitted, could be an autoincrement,
// could also be a "handcrafted" id like classid_userid -> 21_13 (I need this kind of id's for an ember-api.
// All depending on your needs
class // the id of the related class
student // the id of the related student
// maybe add additional fields:
type // to describe that relationship
sort
You then would get all the students of a specific class like so:
$class_id = 1;
$sql = "Select * from students, class_students where students.id=class_students.student AND class_student.class=".$class_id;
// note, that you should do that via prepared statements,
// this is only for simplicity to show how to proceed.

You are not going to add students in the class table. If you do so, there is no point separating class from student in the first( you have prevented redundancy of data ). I believe the table structure is good enough to achieve your objectives. The secondary keys (student_id , class_id) which are primary key in the student and the class tables respectively does the job.
class table
id| title | start | end
1 Biology 8am 10am
2 English 10am 12pm
student table
id | name |
1 John
2 Doe
student_class table
student_id | class_id
1 1
1 2
2 1
from the table, i could
Get all courses John( user.id: 1 ) registered for
SELECT FROM student_class WHERE student.student_id = '1'
All the students that registered for Biology (class.id: 1)
SELECT FROM student_class WHERE student.class_id = '1'
Note I know you will need the name of the student here in the result.
Very simply , just 'LEFT JOIN' class table with student_class table on student_class.class_id = student.id
Then for each record you get from student_class table, the 'name' (or other columns you choose to include in the result set) will be added from the class table.
Note the way you just joined the class table, you can do the same for student table. for example, You want the student to print their time table for classed they registered for, you will still select from student_class table and get the start and the end time using LEFT JOIN

Related

Get same named columns separately after left join in mysql using Eloquent

I have 2 tables one of them stores students and the other one managers
students have name surname,
eventually managers have name and surname too.
I also store added_by in students table to check which manager added the student.
With the query I join tables
$students = \App\Student::with('payment')->with('discontinuities')
->leftJoin('managers','students.added_by','=','managers.id')
->get();
lets say student is
Name Surname Added_by
Jon Doe 1
and Manager is
id name surname
1 jane doe
So when I join those 2 tables with the query I give above. My student becomes
Jane doe because of name conflicts in those 2 tables.
Simply manager's name overwrites to student's name since both columns named same.
I could actually join only some columns in managers table however I need this name column to print out added_by column with the managers name
and of course I can change columns name to something else in a table however this would be too much work because I have to refactor each query in my application one by one and also test everything from scratch
so my question is how can I join those 2 tables and prevent conflictions on columns with same name?
Try using this:
$students = \App\Student::with('payment')->with('discontinuities')
->leftJoin('managers','students.added_by','=','managers.id')
->select('students.*','managers.name as m_name','managers.surname as m_s_name','managers.other_column_if_needed','managers.another_column_if_needed')
->get();
This way your managers table's name column will be treated as m_name and surname column will be treated as m_s_name
I ran into a similar issue earlier today, the 'get' method takes in an array of the column names which you want in the result as parameter. Therefore to prevent the conflicts you have to give those columns an alias name like so :
$students = \App\Student::with('payment')->with('discontinuities')
->Join('managers','students.added_by','=','managers.id')
->get(['students.*', 'managers.name as managers_name', 'managers.surname as managers_surname', 'managers.other_column_if_needed']);
My guess would be that you should specify column names and tables in the get() part of your query.
example:
$students = \App\Student::with('payment')->with('discontinuities')
->leftJoin('managers','students.added_by','=','managers.id')
->get(['managers.Name', 'managers.Surname', 'students.name', 'students.surname']);

php mysql relational definition in tables

guys I've been trying to create create a school results management system.There is a STUDENT table and many COURSE tables. Each student must be linked to all Courses tables. e.g JOHN, MARY,PETER must partake in MATHEMATICS, ENGLISH, ELECTROPHYSICS, PROGRAMMING etc
My problem is how to define this relationship in mysql and at same time let these students fetch only their own results in all the courses.
I don't know if you have a requirement to have each course in a separate COURSE table but that doesn't make much sense. You should have a STUDENT table and a COURSES table. Then, you will need a STUDENT_COURSES table to show which courses a student has taken or must take. Your table structure should be something like:
STUDENT: Id, Name, Gender, etc
STUDENT_COURSES: Id, Student_Id, Course_Id, Taken, Grade
COURSES: Id, Course_Name
When a new student is created, you would need to add records to the STUDENT_COURSES table to insert the new STUDENT.Id into the Student_Id field and the Course_Id for each of the required courses. The default value for Taken would be false and the Grade would be Null or Empty String.
This is a very simplistic example and would not work in a real world solution because you would need to have Instructors, Locations, Etc. to make anything useful. But hopefully this will help you get started.

Choice of tables for handling attendance

I'm working on my project in PHP [handling students attendance system]. I have a list of students along with their id[jntuno] and I need to create a database in mysql for storing the daily attendance of each student for each subject.So I created my tables in this way :
TABLE : students
FIELDS:
slno int(5) auto increment,
jntuno char(15),
name char(50),
primary key(slno,jntuno).
DATA:
this students table holds the list of students and their id
now I created another table :
TABLE: dailyatt
FIELDS:
date date,
subject char(10),
classesconducted int(2),
`11341A0501` int(2),
`11341A0502` int(2),
`11341A0503` int(2),
.
.
.
`11341A0537` int(2),
primary key(date,subject).
this table will look like :
+------------+-----------+-----------------+------------+-----------+-----------+
|date |subject |classesconducted |11341A0501 |11341A0502 |11341A0503 |....
+------------+-----------+-----------------+------=-----+-----------+-----------+
| | | | | | |
now every day upon entering the attendance in the PHP website, a new row will be created for each subject taught on that day.
But many said that the database model is not a good one ...
What's wrong with this database structure?
So can someone suggest me a better model for this kind of problem?
Image you have 200 students offered at your school. You would have 200+ columns in your second table. You should split it up to two tables. One for all the classes that are offered at school and the second for the actual attendance records.
"classes" table
"attendance table"
Then join them together.
SELECT student_id, class_name, date, class_attended
FROM attendance AS ABB2
LEFT JOIN classes AS ABB1 ON ABB1.id = ABB2.class_id
You are creating a column for every student, I think is the bad thing.
Why you just not create table like this one?
`date` date,
`slno` int(5),
`slnoconducted` int(2),
`subject` char(10),
primary key(`date`, `slno`, `subject`)
So, you can insert in this table some values like:
("2013-10-06", 1, 5, "Class A")
And it will be treated as: By the date 2013-10-06 the student with slno #1 (11341A0501) gained slnoconducted == 5 with the description "Class A".
After, if you want, for example, to get all records today, you can use query:
SELECT * FROM dailyatt WHERE `date` = '2013-10-06'
If you want to get all records for one student, you can use query:
SELECT * FROM dailyatt WHERE `slno` = 1
And even:
SELECT d.*, s.`jntuno`, s.`name`
FROM `dailyatt` d
LEFT JOIN `students` s ON d.`slno` = s.`slno`
WHERE `date` = '2013-10-06'
It is better way to deal with records. If you will create column for every student, you will lose flexibility of the DB, because you will have to create/delete another column after any changes in students table.
I hope I described it correctly, because I'm not sure I have good English.

Storing multiple checklist data in MySQL using PHP

i have a table which consists of student details like roll no, Name, age. Now i have a table for storing the students who have attended and not attended on the given day and given class. I will be using a form with checklist and names automatically displayed using the student details table, i.e. All the name name and roll no will get displayed with a checkbox to each name. If it checked, it mean the particular student has attended the class and if not checked, then the student didn't attended. These detail should get update in the attendance table. How to do it using php and MySQL?
Use a many to many relation in MySQL.
You have a database table with students, like:
Table classes
Student (primary)
StudentName
StudentAge
(further info)
Create a database table for the Classes with they can attend, like:
Table classes
ClassID (primary)
ClassName
ClassDate
(further info)
Then create a many to many table, like:
Table attendances
ClassID (primary)
StudentID (primary)
To get the students that attended the class do the following query:
<?php
$lstrQuery = "SELECT `students`.* FROM `students`
INNER JOIN `attendances` ON `attendances`.`StudentID` = `students`.`StudentID`
AND `attendances`.`ClassID` = {YOUR_CLASS_ID} ";
$loResult = mysql_query($lstrQuery);
while($laRow = mysql_fetch_assoc($loResult))
{
// do whatever you like
}
?>
Is this what you had in mind?

PHP select row from db where ID is found in group of IDs

I have 3 employers IDs: 1, 2 and 3. I am generating tasks for each one by adding a line in database and in column "for_emp" I insert IDs I want to assign this task for and could be all 3 of them separated by comma. So let's say I got a task and "for_emp" is "1,2,3", the employers IDs. If I would like to select all tasks for the ID 2, will I be able to select from the row that has "1,2,3" as IDs and just match "2" there ? If not, how do you suggest I insert my emp IDs into one row in database ? The db is MySQL.
Any ideas ? Thanks.
Don't do it like that, you should normalize your database.
What you want to do is have a table such as task, and then task_assignee. task_assignee would have fields task_id and user_id. If a task has eg. three assignees (IDs 1, 2 and 3), then you'll create three rows in the task_assignee table for that one task, like this:
+--------+---------+
|task_id | user_id |
+--------+---------+
| 1 | 1 [
| 1 | 2 [
| 1 | 3 [
+--------+---------+
Then it's just a simple matter of querying the task_assignee table to find all tasks that are assigned to a given user.
Here's an example of how to get all the tasks for user_id 2:
SELECT t.* FROM task AS t INNER JOIN task_assignee AS ta WHERE ta.user_id = 2
EDIT.
Just as a related note, even if you didn't do it the right way (which I described in my answer previously), doing it with hacks such as LIKE would still be far from the optimal solution. If you did store a list of comma-separated values, and needed to check if eg. the value 2 is in the list, you could use the MySQL's FIND_IN_SET function:
SELECT * FROM task WHERE FIND_IN_SET(2, for_emp)
But you shouldn't do this unless you have no choice (eg. you're working with someone's shitty DB design), because it's way more inefficient and won't let you index the the employee ID.
The following query should do what you want:
SELECT * FROM tasks WHERE for_emp LIKE '%2%';
However, be aware that that would also match employers 12, 20, 21 etc; so take care if you expect you might end up in double-digits.
However, the other answers about renormalising your database are definitely preferable.
You're doing it wrong. Create a relation table with two fields: employee id and task id. If one task should be assigned to three employees, insert three rows in the relation table.
You then use JOIN to join the task, employee and relation tables.
then its no proper relation...
I would suggest a "mapping table" for the n:m relation
employee
id
task
id
employeetask
task_id
employee_id
Make a table for your employers. Insert your three rows in it.
Then make a table for mapping tasks to employers. If a task is assigned to three employers, insert three rows into this table. This is basic entity-relation work.
I would make 2 different tables.
1 with employees, and 1 with tasks.
then make another table which combines the two tables, I will call it Assigned Tasks.
Then in assigned tasks I make a assigned id, a employeenumber which is a FK to the employee table and a taskid which is a FK to the Tasks table.
If an employee has more than 1 task. Just insert another row in the assigned table. ;)
When its about Databases, try to think in solo entities! Combining those entities is able in antoher table.
sql example:
Select * from Assignedtasks where employeeID = 1 will give you all his/her tasks. :)
You could use a LIKE '%,2,%' clause in your SELECT statement.
eg:
SELECT * FROM table where for_emp LIKE '%,2,%'
However performance of such non-sargable queries is usually quite bad.
I would suggest that you insert a row each for each employee who is assigned to the task using a separate TASK_EMPLOYEE_MAPPING table with taskId, employeeId as a composite primary key.
With such a design, your query will be
SELECT * FROM TASK_EMPLOYEE_MAPPING WHERE employeeId = '2'

Categories