I am a beginner with SQL syntax. I have 2 tables called STUDENT and EXAMINATION and I am, in 1 line, trying to write a query to print ID, SUBJECT and NUMBER_OF_TIMES. I am not told which column belongs to which table but my guess is that ID belongs to STUDENT and SUBJECT belongs to EXAMINATION. NUMBER_OF_TIMES is just how many times the same student has taken that subject exam.
I tried SELECT STUDENT.ID, EXAMINATION.SUBJECT, NUMBER_OF_TIMES but no luck.
Your working query would look something like this:
SELECT
s.ID,
e.SUBJECT,
COUNT(e.STUDENT_ID) AS cnt
FROM STUDENT s
LEFT JOIN EXAMINATION e
ON s.ID = e.STUDENT_ID
GROUP BY
s.ID,
e.SUBJECT
This answer assumes, really out of necessity, that there exists a join column STUDENT_ID in the exam table, which connects with the student table. We use a left join so as to report all students, even those with a zero count.
Related
The code below is completely wrong and does not work at all. Im basically trying to look through my tables and compile a list of DeptName and the total student number for a department where a department has more than 40 students.
Im confused about joins in general and if someone could explain and show where im going wrong. im sure there is also other problems so any help with them would help
So basically one department is connected to one module, and a student is enrolled in a module. A student cannot take a module outside of their department. So each student should have one module that connects to one department
All of the ID fields in other tables are foreign keys as you can guess and changing the tables is not what I want to do here I just want to do this query as this stands
Relevant tables columns
Table Department DeptID, DeptName, Faculty, Address
Table Modules ModuleID, ModuleName, DeptID, Programme
Table Students StudentID,StudentName,DoB,Address,StudyType,`
Table Enrolments EID,StudentID,ModuleID,Semester,Year
SELECT Department.DeptName, COUNT(Student.StudentID) AS 'No of Students' FROM Department LEFT JOIN Module ON Department.DeptID= Module.DeptID LEFT JOIN Enrolment ON Module.ModuleID= Enrolment.StudentID LEFT JOIN Student.StudentID
GROUP BY(Department.DeptID)
HAVING COUNT(Student.StudentID)>=40
I have not included every table here as there are quite a lot.
But unless i've got this completely wrong you don't need to access a ModuleID in a staff table for the module they teach or something not relevant to this at all. As no student or Dept details are in there.
If that is the case i will fix it very quickly.
SELECT Department.DeptName, COUNT(Student.StudentID) AS 'No of Students'
FROM Department
LEFT JOIN Module
ON Department.DeptID= Module.DeptID
LEFT JOIN Enrolment
-- problem #1:
ON Module.ModuleID= Enrolment.StudentID
-- problem #2:
LEFT JOIN Student.StudentID
-- problem #3:
GROUP BY(Department.DeptID)
HAVING COUNT(Student.StudentID)>=40
You're joining these two tables using the wrong field. Generally when the modeling is done correctly, you should use USING instead of ON for joins
The right side of any JOIN operator has to be a table, not a column.
You have to group by every column in the select clause that is not part of an aggregate function like COUNT. I recommend that you select the DeptID instead of the name, then use the result of this query to look up the name in a subsequent select.
Note : Following code is untested.
WITH bigDepts AS (
SELECT DeptId, COUNT(StudentID) AS StudentCount
FROM Department
JOIN Module
USING ( DeptID )
JOIN Enrolment
USING ( ModuleID )
JOIN Student
USING ( StudentID )
GROUP BY DeptID
HAVING COUNT(StudentID)>=40
)
SELECT DeptID, DeptName, StudentCount
FROM Department
JOIN bigDepts
USING ( DeptID )
Instead of left join you need to use inner join since you need to select related rows only from those three tables.
Groupy by and having clause seems fine. Since you need departments with more than 40 students instead of >= please use COUNT(e.StudentID)>40
SELECT d.DeptName, COUNT(e.StudentID) AS 'No of Students' FROM Department d INNER JOIN Module m ON d.DeptID= m.DeptID inner JOIN Enrolment e ON m.ModuleID= e.StudentID LEFT JOIN Student.StudentID
GROUP BY(d.DeptName)
HAVING COUNT(e.StudentID)>40
So your join clause was a bit iffy to students as you wrote it, and presumably these should all be inner joins.
I've reformatted your query using aliases to make it easier to read.
Since you're counting the number of rows per DeptName you can simply do count(*), likewise in your having you are after counts greater than 40 only. Without seeing your schemas and data it's not possible to know if you might have duplicate Students, if that's the case and you want distinct students count can amend to count(distinct s.studentId)
select d.DeptName, Count(*) as 'No of Students'
from Department d
join Module m on m.DeptId=d.DeptId
join Enrolment e on e.StudentId=m.ModuleId
join Students s on s.StudentId=e.studentId
group by(d.DeptName)
having Count(*)>40
Also, looking at your join conditions, is the Enrolement table relevant?
select d.DeptName, Count(*) as 'No of Students'
from Department d
join Module m on m.DeptId=d.DeptId
join Students s on s.StudentId=m.moduleId
group by(d.DeptName)
having Count(*)>40
I'm trying to learn SQL and have this question: print the name of all employees together with the name of their supervisor.
Here is my Employees table:
Table Employee
How do I use a SELECT command in new query to get the result out? I tried with a self join.
Ty
Max (SQL NOOB)
Try the below
SELECT t1.EmployeeName AS Manager, t2.EmployeeID as EmployeeName
FROM Employee t1
LEFT JOIN Employee t2 ON t1.ManagerID=t2.EmployeeID
An inner join should do it. Here's the syntax, but you'll have to apply it to your database:
SELECT c.name, o.name
FROM cats c
INNER JOIN owners o
ON c.owner_id = o.id
"cats c" basically means "Cats table, which I'm nicknaming c." "owners o" basically means "Owners table, which I'm nicknaming o." In your select, you tell it which fields you want by their name, and which table their in: [table nickname].[fieldname]. The ON is where you specify a common field from each table, which tells it how to join the two tables together. In the case of this example, we're saying that we want the owner who's id is equal to the owner id field of the cats table. The owner_id field is a foreign key of the owners table.
I know answers like this are frustrating when you're learning, but the truth is you'll learn better if you have to figure a bit out for yourself, and I can't do your homework for you (I mean that nicely..)
I have the two tables STUDENT and TaskEffort.
Many students have worked on same tasks. For a particular task the name of the students and effort should be considered.
The STUDENT table contains studentid, firstName and lastName.
The TaskEffort table contains taskid, studentid and Effort
I need to display the taskid, first name, last name, effort, for those who worked on a particular task.
This is one of the queries I tried, but this is not working.
SELECT t.id, s.firstname, s.lastname, t.effort
FROM taskeffort t
LEFT OUTER JOIN student s ON t.id = 4 AND s.studentid = t.studentid
Thanks in advance.
First the design is not accurate.
You said that "Many students must have worked on same task" but your design is
1-many students. It means that each task has only one student. You need to change the design to support you requirements.
this relation is many-to-many. Student can be assigned to many tasks and tasks may have been assigned to many students.
Add a third table called taskAssignments with columns: student_id,task_id and remove student_id column from TaskEffort.
Then run this query:
SELECT t.id, s.firstname, s.lastname, t.effort
FROM TaskEffort t
LEFT JOIN taskAssignments ta ON t.id=ta.task_id
LEFT JOIN student s ON s.studentid = ta.studentid
WHERE t.id = 4
SELECT t.id, s.firstname,s.lastname, t.effort
FROM taskeffort t
LEFT OUTER JOIN student s ON s.studentid = t.studentid
WHERE t.id = 4;
Using a university relation (students are advised by instructors in different departments, only one advisor per student but advisors can have zero to many advisees), I'm attempting to write a function that computes the total number of students being advised in a given department.
Here are the tables and columns for reference:
student(id,name,dept_name,tot_cred)
instructor(id,name,dept_name, salary)
advisor(s_id,i_id)
I already know how to use delimiter and such so no I don't need to be told how to write a function. I'm just having issues getting what I want from the select statement alone.
This is the best I've been able to come up with so far:
SELECT *
FROM advisor
RIGHT OUTER JOIN instructor
ON i_id=id
ORDER BY dept_name;
This statement yields:
Is there a way I can write an if statement or some other statement to delete all of the NULL entries and then use a count function (within the custom function I'll be writing) that will count the number of instances dept_name occurs, resulting in the total number of advisees per department?
SELECT i.dept_name, COUNT(a.s_id)
FROM Instructor i
LEFT JOIN advisor a ON i.id = a.i_id
GROUP BY i.dept_name;
This will include zeros for departments with no advisees.
If you are interested in the number of advised students per student department then:
SELECT s.dept_name, COUNT(a.s_id)
FROM student s
LEFT JOIN advisor a ON a.s_id=s.id
GROUP BY s.dept_name
OTOH, if you are interested in the number of advised students per instructor department then:
SELECT i.dept_name, COUNT(a.s_id)
FROM instructor i
LEFT JOIN advisor a ON a.i_id=i.id
GROUP BY i.dept_name
It looks like this is what you need:
SELECT i.dept_name, COUNT(a.s_id) FROM instructor i
LEFT OUTER JOIN advisor a ON i.id = a.i_id
GROUP BY i.dept_name;
I have to add that advisor(s_id,i_id) is bad database design if a student really can not have more than 1 advisor as you said. Because in that case, simply add advisor_id to the student relation and get rid of the advisor table.
Also: your use of the word 'function' is incorrect. We are talking about queries here.
Probably you can try this:
SELECT i.dept_name, COUNT(s.*) AS totalAdvisedNum
FROM student s, advisor a, instructor i
WHERE a.s_id = s.id AND a.i_id = i.id GROUP BY i.dept_name
This will select the department name and total number of students being advised by instructors in these departments
If you need to get the number for a specific department you should replace GROUP BY i.dept_name with AND i.dept_name = "name of department"
I have 3 tables teacher subject and assignments. When a teacher logs in, I want to display all the subjects regardless if he is the teacher and regardless if there is related records or not. If there is no related records (assignments) i want it to display 0.
Teacher Table: Teacher_PK, Teacher_name
Subject Table: Subject_PK, Teacher_fk, Subject_name,
Assignments Table: Assignment_PK, Subject_fk, assignment_name
Right now i have it like this:
"SELECT *, count(a.subject_fk)
FROM assignment AS b
LEFT OUTER JOIN subject AS a
ON a.subject_fk = b.subject_PK
WHERE a.teacher_fk = $sessionVar
GROUP BY b.subject_fk
ORDER BY b.subject_name ASC";
The problem with this query is that it does not show all subjects, it only shows the subject if there are related tables.
English (3)
Math(2)
What i want it to display is
English(3)
Math(2)
Gym(0)
Science(0)
Thank you for any help.
All subjects in the Subject table
SELECT
s.*,
count(a.assignment_pk) as numAssignments
FROM
Subject s
LEFT OUTER JOIN Assignments a ON
s.Subject_pk = a.Subject_fk AND
a.teacher_fk = $sessionVar
GROUP BY
s.*
ORDER BY
s.subject_name ASC
edit - moved the filter on teacher id to the outer join section