Count the sum of a left outer join table - sql

I have two tables which is
Student
ID
Name
Gender
Address
1
Abby
Girl
street
2
Mark
Boy
street
3
Lula
Girl
street
4
Bren
boy
street
Lessons
ID
Lessons_code
3
MK2234
5
22324KL
6
KCS233
and I want to join these tables then get the sum result of the students that didn't took a lesson then group it by gender like this:
Gender
total
Boy
2
girl
1
I know it use sum() and left outer join (?) but I don't know how to implement it.

I would suggest not exists:
select s.gender, count(*)
from students s
where not exists (select 1
from lessons l
where l.id = s.id
)
group by s.gender;
You have a very awkward data model. I would expect a column called lessons.id to refer to the primary key of the lessons table. Instead. it seems to refer to a student. A better name would be student_id.

Related

how to join three tables if many id pointing from one table to another table? [duplicate]

This question already exists:
How to join three tables or more than three tables if many ID is pointing from one table to another table?
Closed 3 months ago.
I am confused here about joining suppose I have three tables here student table, course table, teacher table
'student' table
std_Id std_Name course_Id teacher_Id
1 Amit 3 1
2 Yogesh 1 1
3 Pravin 3 2
4 Nilay 1 3
5 Abhijit 2 3
'course' table
course_Id course_Name std_Id teacher_Id
1 JAVA 1 3
2 C# 1 3
3 C++ 3 1
4 SAP 2 2
5 PYTHON 2 1
6 JAVASCRIPT 3 2
'teacher' table
teacher_Id teacher_Name std_Id course_Id
1 Roy 1 1
2 John 2 1
3 Ben 1 3
4 Renu 2 3
5 Ramesh 1 3
Here I am not giving any reference key so how to join three tables I am giving query here
select Std_Name,Course_Name,Teacher_Name
from Student
inner join Course
on 𝐒𝐭𝐮𝐝𝐞𝐧𝐭.𝐒𝐭𝐝_𝐈𝐝=𝐂𝐨𝐮𝐫𝐬𝐞.𝐂𝐨𝐮𝐫𝐬𝐞_𝐈𝐝
or 𝐒𝐭𝐮𝐝𝐞𝐧𝐭.𝐂𝐨𝐮𝐫𝐬𝐞_𝐈𝐝=𝐂𝐨𝐮𝐫𝐬𝐞.𝐒𝐭𝐝_𝐈𝐝
or 𝐒𝐭𝐮𝐝𝐞𝐧𝐭.𝐂𝐨𝐮𝐫𝐬𝐞_𝐈𝐝=𝐂𝐨𝐮𝐫𝐬𝐞.𝐂𝐨𝐮𝐫𝐬𝐞_𝐈𝐝
or 𝐒𝐭𝐮𝐝𝐞𝐧𝐭.𝐒𝐭𝐝_𝐈𝐝=𝐂𝐨𝐮𝐫𝐬𝐞.𝐒𝐭𝐝_𝐈𝐝
inner join Teacher
on 𝐂𝐨𝐮𝐫𝐬𝐞.𝐂𝐨𝐮𝐫𝐬𝐞_𝐈𝐝=𝐓𝐞𝐚𝐜𝐡𝐞𝐫.𝐓𝐞𝐚𝐜𝐡𝐞𝐫_𝐈𝐝
or 𝐂𝐨𝐮𝐫𝐬𝐞.𝐓𝐞𝐚𝐜𝐡𝐞𝐫_𝐈𝐝=𝐓𝐞𝐚𝐜𝐡𝐞𝐫.𝐂𝐨𝐮𝐫𝐬𝐞_𝐈𝐝
or 𝐂𝐨𝐮𝐫𝐬𝐞.𝐓𝐞𝐚𝐜𝐡𝐞𝐫_𝐈𝐝=𝐓𝐞𝐚𝐜𝐡𝐞𝐫.𝐂𝐨𝐮𝐫𝐬𝐞_𝐈𝐝
or 𝐂𝐨𝐮𝐫𝐬𝐞.𝐓𝐞𝐚𝐜𝐡𝐞𝐫_𝐈𝐝=𝐓𝐞𝐚𝐜𝐡𝐞𝐫.𝐓𝐞𝐚𝐜𝐡𝐞𝐫_𝐈𝐝
As you can see I have three tables here so now I want to see the students who have courses and teachers so let's look up here in the student table, we have std_id,course_id, and teacher_id and of course I want to show students who have courses them which column should be used here because in the student table we have std_id and course_id as well so which one should be used to join with course table std_id or course_id of student table and in the course table we have course_id and std_id as well so which column should be used here to join with student table and we also want to show teachers then student table also has teacher_id and course table also has teacher_id so which table's column should be used here to show teacher ?
So which condition should be used here to join three tables because here you can see many ids pointing from one table to another table that`s why I was not able to understand this you know how to join these three tables and get the output please help me someone how can I solve this and please let me know guys please give me answer and I have mentioned above what I want to show here in the output.
Your question could use some formatting but from what I understand you want to join the 3 tables and that should look something like this:
select
s.Std_Name,
c.Course_Name,
t.Teacher_Name
from Student s
inner join Course c on c.Course_ID = s.Course_ID
inner join Teacher t on t.Course_ID = c.Course_ID
You should start using aliases (from Student t) as well as it makes it a lot easier and faster to join and reference tables.
Edit:
Think of the query above like this. A Student attends one (or more) Courses and each course has a Teacher that teaches it. Now the common thing between the Student and the Course is Course_id and that is why we joined it like this s.Course_id = c.Course_id. Now, we know that each Course has a Teacher that teaches it so the common thing between them is also Course_id thus the join is as follows inner join t.Course_id = c.Course_id.

How to make sure result pairs are unique - without using distinct?

I have three tables I want to iterate over. The tables are pretty big so I will show a small snippet of the tables. First table is Students:
id
name
address
1
John Smith
New York
2
Rebeka Jens
Miami
3
Amira Sarty
Boston
Second one is TakingCourse. This is the course the students are taking, so student_id is the id of the one in Students.
id
student_id
course_id
20
1
26
19
2
27
18
3
28
Last table is Courses. The id is the same as the course_id in the previous table. These are the courses the students are following and looks like this:
id
type
26
History
27
Maths
28
Science
I want to return a table with the location (address) and the type of courses that are taken there. So the results table should look like this:
address
type
The pairs should be unique, and that is what's going wrong. I tried this:
select S.address, C.type
from Students S, Courses C, TakingCourse TC
where TC.course_id = C.id
and S.id = TC.student_id
And this does work, but the pairs are not all unique. I tried select distinct and it's still the same.
Multiple students can (and will) reside at the same address. So don't expect unique results from this query.
Only an overview is needed, so that's why I don''t want duplicates
So fold duplicates. Simple way with DISTINCT:
SELECT DISTINCT s.address, c.type
FROM students s
JOIN takingcourse t ON s.id = t.student_id
JOIN courses c ON t.course_id = c.id;
Or to avoid DISTINCT (why would you for this task?) and, optionally, get counts, too:
SELECT c.type, s.address, count(*) AS ct
FROM students s
JOIN takingcourse t ON s.id = t.student_id
JOIN courses c ON t.course_id = c.id
GROUP BY c.type, s.address
ORDER BY c.type, s.address;
A missing UNIQUE constraint on takingcourse(student_id, course_id) could be an additional source of duplicates. See:
How to implement a many-to-many relationship in PostgreSQL?

SQL: Unable to find a join or union to produce the following table

A Pupil table with { ID, LastName}
a Subject Table with {ID, SubjectName}
and a Report Table with {ID, PupilID, SubjectID, Grade}
There is a one-to-many relationship between Pupil and Report Tables, and Subject and Report Tables.
I want to generate a table like this for say subjectID = 1
Pupil.ID Pupil.LastName SubjectID Grade
1 --------------Smith ---------- 1 ------------B
2 --------------Jones ---------- 1 ------------NULL
3 -------------Weston ----------1 ------------NULL
4 -------------Knightly ---------1 -----------A
The problem is that the Report table would contain just 2 entries for subject 1:
PupilID SubjectID Grade
----1------- 1 ----------- B
----4------- 1 ----------- A
Left joins don't seem to work since there are only 2 entries in the report table for subject 1
SAMPLE DATA
{Pupil Table}
ID LastName
1 ...Smith
2 ...Jones
3 ...Weston
4 ...Knightly
{Subject Table}
ID SubjectName
1 ....Maths
2 ....Physics
3 ....Chemistry
{Report Table}
ID PupilID SubjectID Grade
1 .......1 ..........1 ..........B
2 .......4 ..........1 ..........A
When I do a search on SubjectID = 1 I want the table:
Pupil.ID .......Pupil.LastName ........SubjectID ...........Grade
1 --------------Smith ---------- 1 ------------B
2 --------------Jones ---------- 1 ------------NULL
3 -------------Weston ----------1 ------------NULL
4 -------------Knightly ---------1 -----------A
Access doesn't do subqueries very easily, so everything gets crammed into the FROM clause with a series of wrapped parentheses. Based on your sample data and my fighting Access to stop being unnecessarily difficult, I came up with this:
SELECT ps.Pupil_ID, ps.LastName, ps.Subject_ID, r.Grade
FROM (SELECT * FROM (SELECT ID AS Pupil_ID, LastName FROM Pupil) p,
(SELECT DISTINCT ID AS Subject_ID FROM Subject)) ps
LEFT JOIN REPORT r ON r.PupilID = ps.Pupil_ID AND r.SubjectID = ps.Subject_ID
ORDER BY Pupil_ID, Subject_ID;
The subquery "ps" is a cartesian join of the Pupil and Subject table views that I specified. At this point, your query would look like this:
(LastName column not shown for clarity)
StudentID|SubjectID
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
Now, using that Cartesian join subquery (pupilstudent -> ps), I use a LEFT JOIN to assign the Report table to each unique student's ID and subject ID. Therefore, if a student did not take a particular class, there will be a NULL value in the final result.
I tested this in Access using your sample data and it works on my machine.
Also as a note, it is poor practice to have a field called just ID in each table (e.g. in the Pupil table, ID becomes PupilID). This makes it much easier to use, and it self documents.
Cross join pupil and subject tables and left join result to report table
What you need is a cross join:
SELECT Pupil.ID, Pupil.LastName, SubjectID, Grade FROM
Pupil, Subject LEFT JOIN Report ON Subject.ID=Report.SubjectID
WHERE Subject.ID=1
To combine every pupil with every (or with a particular) subject, use cross join; Then use left join to get the corresponding grades:
select *
from pupil p cross join (select * from subject where id = 1) s
left join report on subjectId = s.id and pupilId = p.id

SQL Query (or Join) for 3 tables

first time asking a question on Stack Overflow... Amazing resource, but there's just one thing that's really baffling me as a newcomer to SQL.
I have three tables and I would like to obtain the names of all the Mentors who are linked to Bob's students.
Table 1: TEACHERS
================
ID Name
================
1 Bob
Table 2: STUDENTS
===================================
STUDENT_ID Name TEACHER_ID
===================================
1 Jayne 1
2 Billy 5
3 Mark 2
Table 3: MENTOR_RELATIONSHIPS
==============================
ID STUDENT_ID MENTOR_ID
==============================
1 1 3
2 2 2
3 3 3
Table 4: MENTORS
=====================
MENTOR_ID Name
=====================
1 Sally
2 Gillian
3 Sean
I would like to run a query to find all of the mentors of Bob's students. So the mentors for all students with TEACHER_ID = 1
In this case Sean would be the result.
I know that it is something to do with Joins, or could I find this using a normal query??
Any help is much appreciated! Many thanks...
this should do the work
select distinct m.name from students s
inner join mentor_ralationships mr on mr.student_id=s.student_id
inner join mentors m on m.mentoir_id=mr.mentor_id
where s.teacher_id=1;
Without joins (not preferred)
SELECT mentors.name FROM mentors
WHERE mentors.id
IN (SELECT MENTOR_RELATIONSHIPS.mentor FROM MENTOR_RELATIONSHIPS
WHERE MENTOR_RELATIONSHIPS.student
IN (SELECT students.id FROM students WHERE students.teacher
= (SELECT teachers.id FROM teachers WHERE teachers.name = 'bob')));
It could be helpful for you as I had to retrieve data from three tables AssignedSubject, Section and SchoolClass when a teacher assigned to specific subject then I have to find out the his class and section details including subjectid which I did this way
select a.StaffID, a.SubjectID, s.ID as SectionId, s.Name as SectionName, S.Remarks as SectionRemarks, sc.ID as ClassId, sc.Name as ClassName, sc.Remarks as ClassRemarks from AssignedSubject a
inner join Section s on a.SectionId=s.ID
inner join SchoolClass sc on sc.ID=s.ClassId where a.StaffID=3068
You could try the following:
SELECT DISTINCT m.name
FROM students s INNER JOIN TEACHERS t ON t.ID = a.TEACHER_ID
INNER JOIN MENTOR_RELATIONSHIPS mr ON mr.Student_id = s.Student_id
INNER JOIN Mentors m ON mr.MENTOR_ID = s.MENTOR_ID
WHERE s.teacher_id = 1 WHERE t.Name = 'Bob';
SELECT TEACHER.NAME, STUDENTS.NAME AS STUDENT NAME, MENTORS.NAME AS MENTOR
FROM TEACHERS JOIN STUDENTS ON TEACHERS.ID = STUDENTS.TEACHER_ID
JOIN MENTOR_RELATIONSHIPS ON STUDENTS.STUDENT_ID =
MENTOR_RELATIONSHIPS.STUDENT_ID
JOIN MENTORS ON MENTOR_RELATIONSHIPS.MENTOR_ID = MENTORS.MENTOR_ID
WHERE TEACHER.NAME = 'Bob' ;

Sql Query Join in Oracle

I have Parent table and multiple child tables with foreign key constraint.
School Table
School ID EduDetails Genders Address_id EDUTYPE
1 2 M 3 FGN
And the child tables like
Education Details
EDU ID EducationType
2 Online
AKA Name
School Id AKA Name
1 Test School
1 School Test
Gender Table
Gender ID Gender Desc
M Male
I am using Left outer join for the parent and school table to fetch the results.
But My issue is, If AKA table has 5 counts matching the school Id and Gender table has only 1 records for that school Id.
So the results comes with 5 duplicate rows with school Information and also other child table information.
Is there any workaround to fix this issue. I tried using subquery and row_number over by function. But it is not working for me. Can anybody help me to solve this issue.
Thanks in advance for your time in looking this issue.
My required output should be like this
School_id AKA Name GenderDesc EductaionType
1 Test School Male Online
1 School Test
So I need to have Null values for the not matching records.
Since you want all the records in the AKA Name table, I've joined on that getting a Row_Number for each row. Then using that Row_Number, LEFT JOIN on the other tables.
SELECT S.SchoolId,
SA.AKAName,
G.GenderName,
ED.EducationType
FROM School s
JOIN
(SELECT SchoolId,
AKAName,
ROW_NUMBER() OVER (PARTITION BY SchoolId ORDER BY AKAName) rn
FROM SchoolAKA
) SA ON S.SchoolID = SA.SchoolId
LEFT JOIN
(SELECT EDUID,
EducationType,
ROW_NUMBER() OVER (ORDER BY EducationType) rn
FROM EduDetails
) ED ON S.EDUID = ED.EDUID AND SA.rn = ED.rn
LEFT JOIN
(SELECT GenderId,
GenderName,
ROW_NUMBER() OVER (ORDER BY GenderName) rn
FROM Genders
) G ON S.GenderId = G.GenderId AND SA.rn = G.rn
Here is the SQL Fiddle.
And here are the results:
SCHOOLID AKANAME GENDERNAME EDUCATIONTYPE
1 School Test Male Online
1 Test School (null) (null)