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'
)
Related
Students Table:
ID | Family_ID | Student_name | F_name
Families Table:
ID | F_name | Contact_No
i want to get all records from students where family_id is repeating.(basically i want to know students Brothers/Sisters records if there is any in student table.
i tried it this way but got wrong output;
SELECT students.*
FROM students
INNER JOIN families
ON families.id = students.family_id
ORDER BY families.id ASC
my query result in image: as you can see some ids are showing once others are more then once, but i think all should appear more then once.
If you want to see only relevant people you don't need to link it to the families table. You can group the student with family_id. Here is your query :
SELECT *
FROM Student
WHERE family_id IN (SELECT family_id
FROM students
GROUP BY family_id
HAVING COUNT(1)>1)
ORDER BY family_id
You could try using a join on subquery for the family_id that have more that one rows in students
SELECT students.*
FROM students
inner join (
select students.family_id
FROM students
group by students.family_id
having count(*)>1
) t on t. family_id = students.family_id
I am trying to select whether or not an entry exists in another table. Here's a simple example:
Two tables:
Student
ID Major
1 CS
2 CS
3 CS
4 CS
Student_Teacher
SID TID
1 A
1 B
1 C
3 B
3 D
The first table has a list of student IDs (key = Student ID)
The 2nd table has a list of student -> teachers (key = Student ID, Teacher ID combination).
I would like to select ALL students (1,2,3,4; one in each row) and a flag for whether or not they have a teacher.
SELECTED:
ID Flag
1 1
2 0
3 1
4 0
I know this is possible to do using group by:
select Student.ID, count(Student_Teacher.TID)
from Student left join Student_Teacher
group by Student.ID
Is there a simpler way?
You can try joining to a derived table that contains the distinct student id values of the second table:
SELECT ID, IF(ST.SID IS NOT NULL, 1, 0) AS FLAG
FROM Student AS S
LEFT JOIN (
SELECT DISTINCT SID
FROM Student_Teacher
) AS ST ON S.ID = ST.SID
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;
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
I have a table like this:
id (PK) name teacher (FK) student (FK)
1 Ron 3 6
Both teacher and student are in another table called people.
people
id (PK) name age
3 Ali 42
6 Jon 12
I would like to perform a query to obtain the following
name teacher's name student's name
Ron Ali Jon
Is this possible? I know I can perform two separate joins, but then I am left with two rows and there is no indication of which name is the teacher and which is the student
select t.name, p1.name teacher_name, p2.name student_name
from t
left join people p1 on (t.teacher=p1.id)
left join people p2 on (t.student=p2.id)
Try this:
SELECT a.name, b.name 'teacher name', c.name 'student name'
FROM mainTablle a
LEFT JOIN people b ON a.teacher = b.id
LEFT JOIN people c ON a.student = c.id
WHERE a.id = 1;