Joining Tables w/out foreign key - mysql

Is it possible to connect tables without foreign key?
For example
tblstudent
Columns:
id
firstname
lastname
middlename
tblgrade
Comluns:
id
quiz
project
exam
tblfinalgrade
Columns:
firstname
lastname
finalgrade
Is it possible to view final grade when searching for and id?

The id in tblStudent is meaningless because you are not referencing it in your other tables. Change your table structure to include this StudentId rather than First Name and Last Name.
For example:
tblGrade
columns:
GradeId
StudentId
Quiz
Project
Exam
tblFinalGrade
FinalGradeId
StudentId
FinalGrade
You can then do:
SELECT ID, FirstName, LAstName, Quiz, Project, Exam, FinalGrade
FROM tblStudent
INNER JOIN tblGrade ON tblGrade.StudentId = tblStudent.StudentId
INNER JOIN tblFinalGrade ON tblFinalGrade.StudentId = tblStudent.StudentId
This would be a better structure than joining on FirstName and Last Name just incase you ever have 5 John Smith how do you know you are returning the correct grades?
Although I am slightly against your original design, you can perform the same query with your existing structure by running the following query:
SELECT ID, FirstName, LAstName, Quiz, Project, Exam, FinalGrade
FROM tblStudent
INNER JOIN tblFinalGrade ON tblFinalGrade.FirstName = tblStudent.FirstName AND tblFinalGrade.LastName = tblStudent.LastName
WHERE tblStudent.ID = 1

Related

Filtering Dates in mySQL

Just started learning SQL and need help on the Feb 1, 2020 part.
The database has three tables for tracking horse-riding lessons:
Horse with columns:
ID - primary key
RegisteredName
Breed
Height
BirthDate
Student with columns:
ID - primary key
FirstName
LastName
Street
City
State
Zip
Phone
EmailAddress
Lesson Schedule with columns:
HorseID - partial primary key, foreign key references Horse(ID)
StudentID - foreign key references Student(ID)
LessonDateTime - partial primary key
Write a SELECT statement to create a lesson schedule for Feb 1, 2020 with the lesson date/time, student's first and last names, and the horse's registered name. Order the results in ascending order by lesson date/time, then by the horse's registered name. Make sure unassigned lesson times (student ID is NULL) appear in the results.
Hint: Perform a join on the LessonSchedule, Student, and Horse tables, matching the student IDs and horse IDs.
This is what I have; not sure of the correct way to go about it. I've tried using WHERE and AND but get an error or only all NULL first/last names in the table.
SELECT LessonDateTime, FirstName, LastName, RegisteredName
FROM LessonSchedule
LEFT JOIN Student ON LessonSchedule.StudentID = Student.ID
INNER JOIN Horse ON LessonSchedule.HorseID = Horse.ID
ORDER BY LessonDateTime, RegisteredName;
Please try this.
I think it will work.
SELECT LessonDateTime, FirstName, LastName, RegisteredName
FROM LessonSchedule
LEFT JOIN Student ON LessonSchedule.StudentID = Student.ID
INNER JOIN Horse ON LessonSchedule.HorseID = Horse.ID
WHERE LessonDateTime = '2020-02-01'
ORDER BY LessonDateTime, RegisteredName;

Sum scores from two tables in MySQL using two fields in the WHERE clause

I have two tables in MySQL. I will call them grade7 and grade8. Both tables have all these fields, StudentID, FirstName, LastName, Total_Score, mathScore and scienceScore. In both tables are Student names, but the StudentIDs in grade7 are not the same as those in grade8, although the FirstName and LastName are uniform ( of the same person). What I am trying to do is sum up the scores from grade7 and grade8 of the same student. Meaning, sum up the scores of a record with FirstName and LastName in grade7 which are equal to FirstName and LastName in grade8. My code below works initially when there are no scores. But if there are scores already there, it seems to add extra scores than what is supposed to be added. Say if it supposed to output 70 as Total_Score, it will add another 10 points and output 80. Please look at my code and advise what I should do. Thank you.
update grade8 o inner join
(
SELECT op.StudentID
sum(ot.Total_Score) as Total_Score_ot
sum(ot.Maths) as Maths_ot
sum(op.Total_Score) as Total_Score_op
sum(op.Maths) as Maths_op
FROM grade7 ot inner join grade8 op
WHERE ot.FirstName = op.FirstName AND ot.LastName = op.LastName
GROUP BY op.FirstName
) as o1
SET Total_Score=Total_Score_op + Total_Score_ot
Maths=Maths_op + Maths_ot
I suggest starting off with a union of the two tables, then aggregating by student. Also, I don't know why you seem to be doing an update here rather than a select.
SELECT FirstName, LastName, SUM(Total_Score) AS Total_Score, SUM(Maths) AS Maths
FROM
(
SELECT FirstName, LastName, Total_Score, Maths FROM grade7
UNION ALL
SELECT FirstName, LastName, Total_Score, Maths FROM grade8
) t
GROUP BY FirstName, LastName;

select info of students that got A on all their exams

I have three tables:
STUDENT
Studentid (pk) | Lastname | Firstname
SUBJECT
Subjectcode (pk) | Subjectyear (pk) | Subjectname
EXAM
Studentid (pk, fk) | Subjectcode (pk, fk) | Subjectyear(pk, fk) | Grade
I need to make a select statement that returns the Studentid, Lastname and Firstname of all the students that only got the grade A on their exams in their subjects.
So let's say that a particular student had exams in three different subjects and got A, B and A, then they shouldn't be included in the result.
If another student had two exams in two different subjects and got A and A, they must be included in the result.
One option is aggregation:
select st.studendid, st.lastname, st.firstname
from student st
inner join exam ex on ex.studendid = st.studendid
group by st.studendid, st.lastname, st.firstname
having min(ex.grade) = max(ex.grade) and min(ex.grade) = 'A'
Actually, assuming that 'A' is the least grade alphabetically-wise, the having clause can be simplified as:
having max(ex.grade) = 'A'
Note that you don't need the subject table to get the result that you are looking for.
Assuming that all students have at least 1 exam, then you can use NOT EXISTS:
select s.* from student s
where not exists (
select 1 from exam
where studentid = s.studentid and grade <> 'A'
)

MySQL: Selecting records that attended two different courses out of 3

I have two tables, a course and an attendance table.
Course table keeps records of offered courses
Attendance table keeps records of students names and emails who attended courses offered and the date they attended.
I need to select all attendance records in which student has attended exactly 2 out of 3 courses offered and output the 3rd unattended course needed to complete the 3 courses.
Course table structure:
id : int
course_title : varchar
course_level : int
Attendance table structure:
id : int
course_id : int
student_name : varchar
student_email : varchar
attended_date : date
Try this solution (as found here)
SELECT t1.email, course.course_title
FROM (SELECT email
FROM attendance
JOIN course
ON attendance.course_id = course.id
AND course.course_level = 1
GROUP BY email
HAVING COUNT(DISTINCT attendance.course_id) = 2) AS t1
CROSS JOIN course
LEFT JOIN attendance
ON attendance.course_id = course.id
AND attendance.email = t1.email
WHERE course.course_level =1
AND attendance.id IS NULL;

Searching on one table with multiple parameters query

I have 2 tables such as below:
Table 1 contain UserID and Name while table 2 contain UserID, Skill_ID, and SkillName
What I want to do is, I want to search someone who has 2 skill, searched via SkillName.
example: I have Andy as Name where he have 2 skill PHP and C# so when i Search PHP & C#, Andy will be shown as result.
Can anybody help me? Thank you.
SELECT a.Name
FROM table1 a
INNER JOIN table2 b
ON a.userID = b.user_ID
WHERE b.skill_name IN ('PHP','C#')
GROUP BY a.Name
HAVING COUNT(*) = 2
the design of your table is not well normalized. The type of relationship is Many-to-Many and in this case, this should be three tables, Users, Skills and the linking table User_Skills.
A suggested design would be:
Table User
UserID (PK)
Name
Table Skills
SkillID (PK)
SkillName
Table User_Skills
UserID (FK)
SkillID (FK)