i have a table with all the students names and another table with student name and their enrollments in classes i want to show both students with their class names even if they are not enrolled in any classes i used union between the enrolled and not enrolled the only problem that the names are duplicated
Student (student_id, student_name, major, level, age)
Enrolled (student_id, class_name, semester)
and here's the MySQL query:
select student_name,class_name from student natural join enrolled union select student_name,null as class_name from student group by student_name;
Does this work for you?
SELECT
s.student_name,
e.class_name
FROM
student s
LEFT JOIN enrolled e ON s.student_id = e.student_id
GROUP BY student_name;
LEFT JOIN is used when one of the tables can have null values, whilst the other can not. The "left" table (student in this case) is the most important one, the "right" table (enrollment) is the one that can be null.
So it will ALWAYS find the student tables, but when it can't find a class_name that's linked to that student, it just shows up as NULL.
If you want multiple enrollments on the same student, you'll have to remove the group by.
You should use LEFT JOIN like so: SELECT s.student_name, e.class_name from student s LEFT JOIN enrolled e ON s.student_id=e.student_id
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
This is a homework question. I am not asking for the correct answer, I am just looking for help whether I am going in the right direction.
The prompt is that I am to return the first and last name of students who either (OR): (a) Is not currently enrolled (not in Enrollments table) or (b) has the lowest score in any class within their own department.
The database schema is as follows:
My SQL query that I came up with is:
SELECT FIRSTNAME, LASTNAME
FROM STUDENTS
JOIN ENROLLMENTS ON STUDENTS.NETID = ENROLLMENTS.NETID
JOIN COURSES ON COURSES.CRN = ENROLLMENTS.CRN
WHERE STUDENTS.NETID NOT IN (
SELECT NETID
FROM ENROLLMENTS
) OR
ENROLLMENTS.SCORE IN (
SELECT MIN(SCORE)
FROM ENROLLMENTS
WHERE COURSES.DEPARTMENT = STUDENTS.DEPARTMENT
GROUP BY ENROLLMENTS.CRN
);
I tried to use JOIN clauses to combine the three tables where they intersect. The NetId is distinct to each student, identifying them in the Enrollments table. Each class has a unique CRN so I connected them there between Courses table and Enrollments table.
I do not know where the problem lies but the expected outcome is:
Wbixik Yjepuriluwe
Wtoyi Avamijosu
Jheyiresoxo Bsexedoh
Ulerusota Mzuzu
But my outcome is:
Wbixik Yjepuriluwe
Jropop Vduyumi
Jheyiresoxo Bsexedoh
Ulerusota Mzuzu
Looking for any guidance to get me back on track.
You can try using left join
SELECT FIRSTNAME, LASTNAME
FROM STUDENTS
left JOIN ENROLLMENTS ON STUDENTS.NETID = ENROLLMENTS.NETID
JOIN COURSES ON COURSES.CRN = ENROLLMENTS.CRN
where ENROLLMENTS.NETID is null OR
ENROLLMENTS.SCORE IN
(SELECT MIN(SCORE) FROM ENROLLMENTS
WHERE COURSES.DEPARTMENT = STUDENTS.DEPARTMENT
GROUP BY ENROLLMENTS.CRN
)
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;
I have three table professor,student and pro_stu where pro_stu contain relationship between professor and student table.
Professor (PID, PNAME).
Student (SID, SNAME).
PRO_STU (PSID, PID, SID).
I want to all student records which student learn from all professor. If you required further information I will give it. I know i have to use join but how to use it I don't know. Thanks.
I want student id=11 which name is hasan which learn by all professor.
I tried following query but no luck
SELECT *
FROM student
INNER JOIN pro_stu ON pro_stu.sid=student.sid
INNER JOIN professor ON professor.pid = pro_stu.pid
SQL Fiddle
I believe here is what you looking for:
SELECT SID, SNAME, count(DISTINCT PID) AS `c` FROM PRO_STU
INNER JOIN Student USING (SID)
GROUP BY SID, SNAME
HAVING `c` = (SELECT count(*) FROM Professor)
I have two tables: subject and student.
I'm trying to count the number of subjects enrolled by each student. How do I do that? I'm trying the code below but it doesn't give the answer I need.
SELECT COUNT( subject.SUBJECT ) , student.IDNO, student.FIRSTNAME, subject.SUBJECT
FROM student, subject
GROUP BY subject.SUBJECT
LIMIT 0 , 30
you do have an Enrolment table too, don't you? to resolve the many-to-many relationship between student and subject. you could work with just that. say, your enrolment table has studentID and subjectID columns, then you would only need:
SELECT studentID, COUNT(*) FROM Enrolment GROUP BY studentId;
or, to include their names too,
SELECT s.firstname, COUNT(*) FROM Enrolment e JOIN student s on e.studentId=s.IDNO GROUP BY e.studentId;
You are missing a join condition. Somewhere you are storing info about what subject each student is taking. Perhaps WHERE subject.student_id = student.id.