How to count the number of students taught by each teacher? - sql

I have a database that has the following tables
Courses: CourseID*, CourseName, TeacherID
Teachers: TeacherID*, TeacherName
Students: StudentID*, StudentName
StudentCourses: CourseID*, StudentID*
Legend: * is the primary key.
How can I write to query that produces produces the number of students taught by each teacher?
For example
TeacherName, Count
Bob 15
Sarah 5
Zubair 1
Edit
select "TeacherName", count(*)
from courses inner join teachers on courses."TeacherID" = teachers."TeacherI"
join sutdentcourses on sutdentcourses."CourseID" = courses."CourseID"
group by "TeacherName"
order by "TeacherName";

You need make JOIN between the tables Teachers, Courses and StudentCourses, Group your records by TeacherName and Count the StudentID.
SELECT TeacherName, COUNT(StudentID)
FROM Teachers JOIN Courses USING(TeacherID)
JOIN StudentCourses USING(CourseID)
GROUP BY TeacherName

Related

SQL select - Get all from exams table where examId exists in subjects table, for all subjects that exist in students table for desired studentId

I have three tables: exams, subjects and students.
Students table has foreign key subjectId and Subjects table has foreign key examId.
I need to retrieve all exams for desired studentId. So I need sql select that will pick up all subjects for that studentId, and pick up all exams for all these subjects.
So pseudo code is something like:
SELECT * FROM exams
WHERE id IN (SELECT examId FROM subjects
WHERE id IN (SELECT subjectId from students
where id === desiredId))
Why are you using subqueries and just not inner join?
Try with this:
Select X.* From exams X
Inner join subjects S on S.examId = X.id
Inner join students T on T.subjectId = s.Id
Where T.id =#yourStudentId

Recursive sql query n to n in SQLite

I have a database table like that
Table student
_______________
id_student int (PK)
student_name VARCHAR
and I have a recursive loop:
A student can oversee many students, and a student can be overseen by many students
so a new table:
Table oversee
________________
id_student pk, fk
id_overseen pk, fk
date date
the problem is that I want to get the list that I have
I made an sql query:
with
sr1 as ( select s.student_name as over from student s, oversee o where o.id_student = s.id_student),
sr2 as (select s.student_name as overseen from student s, oversee o where o.id_overseen = s.id_student)
select distinct * from sr1, sr2;
the problem is that's the query returns the wrong answers
I mean if we have two lines in the table, it will return 4 lines.
I want to get every student with his overseen:
Student | overseen.
Someone has any idea please?
Thanks.
I want to get a table with student | overseen | date
SELECT s.student_name AS student
, s2.student_name AS overseen
, oversee.date
FROM student s
JOIN oversee ON oversee.id_student = s.id_student
JOIN student s2 ON s2.id_student = oversee.id_overseen

multi-relation queries in SQL

Given these four relations:
Mentorship (mentee_id, mentor_id)
Study (sid, credits)
Enrollment (did, sid)
Student (sid, street , city )
I want to write a query that finds all students who live in the same city and street as their mentor, assuming that all mentors and mentees are students.
I tried to write this query as:
SELECT sid
FROM Student, Mentorship
WHERE street IN (SELECT sid
FROM Student, Mentorship
WHERE mentor_sid = sid
AND ... )
It's incomplete but I tried to SELECT a sid from Student and Mentorship relations where street falls into a condition where mentor_sid and mentee_sid has same street and city.
I am new to SQL and still confused how to do these stuffs.
You need to join student (mentee) to student (mentor) via the link table
SELECT s1.* FROM Student s1
INNER JOIN Mentorship m ON s1.sid = m.mentee_id
INNER JOIN student s2 ON s2.sid = m.mentor_id
AND s2.street = s1.street AND s2.city = s1.city

select sections which do not have any students enrolled

I want to select all sections which do not have any students enrolled
These are the three tables:
ENROLLMENTS
student_id, section_id
SECTIONS
course_id, section_id
COURSES
course_id, description
The output table should look like this:
course_id | description | section_id
I'm not shure which join to use.
So you want
SELECT
course_id
, description
, section_id
FROM
COURSES
INNER JOIN
SECTIONS
ON
COURSES.course_id = SECTIONS.course_id
LEFT JOIN
ENROLLMENTS
ON
ENROLLMENTS.section_id = SECTIONS.section_id
WHERE
ENROLLMENTS.student_id IS NULL;
This will take all of the information from COURSES and SECTIONS, then join it to ENROLLMENTS, keeping all of the information for COURSES and SECTIONS where there an no enrollments. Then by selecting where the ENROLLMENTS student_id is NULL we find all the entries that didn't have section_ids in SECTIONS.
Why not using a subquery?
SELECT
sections.course_id,
courses.description,
sections.section_id
FROM
courses INNER JOIN sections ON courses.course_id = sections.course_id
WHERE
courses.section_id NOT IN (SELECT section_id FROM enrollments)

Writing two queries (sort students and cities according to average grades)

I have three tables:
1) Students: studentID (KEY), name, surname, address
2) Exams: examID (KEY), examName
3) Grades: studenID (KEY), examID(KEY), grade
How to write SQL query to show the best students (for example those with average grade above 9)?
How to write SQL query to rank Cities (column address) according to the average grade of their students?
I'm a system engineer, working with Unix and Linux systems and I am new in SQL, I only know about SQL basics, and I was trying to do this for past three days, with no success, so please help me. I presume it's not a complex thing for one who's experienced in SQL. Thanks a lot.
your first query to show the best students :
SELECT student.surname, students.surename, students.address
FROM
students INNER JOIN Grades ON Grades.StudentID=Students.StudentID
INNER JOIN Exams ON Grades.examID=exams.examID WHERE Grades.grade=
(SELECT MAX(grade) FROM Grades WHERE examID=exams.examID)
your second query to rank cities:
SELECT students.address
FROM
students INNER JOIN Grades ON Grades.StudentID=Students.StudentID
INNER JOIN Exams ON Grades.examID=exams.examID order by grades.grade DESC
Refer the fiddle here:
LINK 1 : http://sqlfiddle.com/#!4/ab4de6/19
LINK 2 : http://sqlfiddle.com/#!4/ab4de6/32
Below Queries should help you in Oracle:
--List of Students having Average grade >=9
SELECT S.studentID, S.NAME, S.SURNAME, S.ADDRESS, A.AVG_GRADE FROM
STUDENTS S JOIN
(
SELECT studentID, AVG(GRADE) AVG_GRADE FROM GRADES
GROUP BY studentID
) A
ON S.studentID = A.studentID
AND A.AVG_GRADE >=9
ORDER BY A.AVG_GRADE, S.studentID;
--------------------------------------------------------------------
--- Rank cities
SELECT A.ADDRESS, A.AVG_GRADE, ROWNUM RANKING FROM
(
SELECT S.ADDRESS, AVG(G.GRADE) AVG_GRADE FROM
STUDENTS S JOIN GRADES G
ON S.STUDENTID = G.STUDENTID
GROUP BY S.ADDRESS
ORDER BY 2 DESC
) A;
You need to know about the following concepts.
INNER QUERY / SUB QUERY
JOINS
AGGREGATE FUNCTIONS (Average Calculations)
GROUP BY
ORDER BY
ROWNUM