SQL find teacher courses query - sql

I am trying to get teacher FIRSTNAME, LASTNAME and count of courses he got. Oracle database. CLASS table has columns: CLASSID, TEACHERID, CLASSNAME Current code:
SELECT DISTINCT FIRSTNAME, LASTNAME, COUNT(TEACHERID)
FROM PERSON
INNER JOIN TEACHER T ON PERSON.PERSONID = T.TEACHERID
INNER JOIN CLASS C ON T.TEACHERID = C.TEACHERID
WHERE T.TEACHERID = C.TEACHERID;
Where is my mistake?

Sounds like you need a GroupBy:
SELECT FIRSTNAME, LASTNAME, COUNT(T.TEACHERID)
FROM PERSON
INNER JOIN TEACHER T ON PERSON.PERSONID = T.TEACHERID
INNER JOIN CLASS C ON T.TEACHERID = C.TEACHERID
GROUP BY LASTNAME,FIRSTNAME
By the way, I initially deleted this answer because it's not a good way to do the grouping. I'd instead prefer grouping by TEACHERID, then joining back to get the names, rather than grouping by names.
I think this is a better approach:
SELECT FIRSTNAME, LASTNAME, C.NUMCLASSES
FROM PERSON
INNER JOIN TEACHER T ON PERSON.PERSONID = T.TEACHERID
INNER JOIN (SELECT TEACHERID, COUNT(CLASSID) AS NUMCLASSES FROM CLASS GROUP BY TEACHERID) C
ON C.TEACHERID=T.TEACHERID

you are missing the GROUP BY clause after the WHERE clause
GROUP BY FIRSTNAME, LASTNAME --all the selected columns except those in aggregate functions such as COUNT

May be you can try
SELECT FIRSTNAME, LASTNAME,
(select COUNT(C.TEACHERID) form CLASS C ON T.TEACHERID = C.TEACHERID)
as COURSECOUNT
FROM PERSON
INNER JOIN TEACHER T ON PERSON.PERSONID = T.TEACHERID

Related

sql programming all type

Write a query to display list of students name who all are from IT department. Sort the result based on students name in descending.
This query will work for any rdbms and any schema (I assume that's what you are after here)
select studentid, firstname, surname
from tblStudent s
inner join tblStudentDepartment sd on s.studentid = sd.studentid
inner join tblDepartment d on sd.departmentid = d.departmentid
where d.department = 'IT'

SQL Find student names according to grade

I am trying to print student names for each student that has more than one "2" grade. Grade is integer from CLASSSTUDENT table. Oracle database.
Code so far:
SELECT DISTINCT FIRSTNAME, LASTNAME
FROM PERSON
JOIN STUDENT ON PERSON.PERSONID = STUDENT.STUDENTID
JOIN CLASSSTUDENT ON STUDENT.STUDENTID = CLASSSTUDENT.STUDENTID
WHERE FINALGRADE = 2;
This get students having grade of "2". How must I change query to get students with more than one "2" grade?
SELECT FirstName, LastName
FROM Person p
INNER JOIN Student s ON p.PersonID = s.StudentID
INNER JOIN (
SELECT StudentID
FROM ClassStudent
WHERE FinalGrade = 2
GROUP BY StudentID
HAVING COUNT(*) > 1
) f ON f.StudentID = s.StudentID
or more simply:
SELECT FirstName, LastName
FROM Person p
INNER JOIN ClassStudent cs ON cs.StudentID = p.PersonID
WHERE cs.FinalGrade = 2
GROUP BY cs.StudentID, FirstName, LastName
HAVING COUNT(*) > 1
Though I prefer the former for reasons I don't myself fully understand (possibly something to do with only grouping on the primary key, or only using the group to filter the records... but really it just "feels" more right somehow).
I believe it would be something like:
SELECT FIRSTNAME, LASTNAME, COUNT(*)
FROM PERSON
JOIN STUDENT ON PERSON.PERSONID = STUDENT.STUDENTID
JOIN CLASSSTUDENT ON STUDENT.STUDENTID = CLASSSTUDENT.STUDENTID
WHERE FINALGRADE = 2
GROUP BY FIRSTNAME, LASTNAME
HAVING COUNT(*) >= 2;

SQL query find records that not persists in other tables

I need to print all persons which are not students and not teachers. I have three tables. Oracle database. Code so far:
SELECT PersonID, FirstName, LastName, Gender, DateOfBirth
FROM PERSON
INNER JOIN STUDENT S ON PERSON.PersonID = S.StudentID
INNER JOIN TEACHER T ON PERSON.PersonID = T.TeacherID
WHERE PERSON.PersonID != S.StudentID
AND PERSON.PersonID != T.TeacherID;
I guess my query is wrong because it returns 0 results. Do you have any idea what must I change?
" my query is wrong because it returns 0 results"
Inner joins return records when there is a match. You're trying to find PERSON records which join to neither STUDENT nor TEACHER. So, change your query to use outer joins:
SELECT PersonID, FirstName, LastName, Gender, DateOfBirth
FROM PERSON
LEFT OUTER JOIN STUDENT S ON PERSON.PersonID = S.StudentID
LEFT OUTER JOIN TEACHER T ON PERSON.PersonID = T.TeacherID
WHERE S.StudentID is null
AND T.TeacherID is null;
This is an anti-join: it returns records from PERSON which don't match records in STUDENT and TEACHER.
Use not exists:
select p.*
from person p
where not exists (select 1 from teacher t where t.teacherid = p.personid) and
not exists (select 1 from students s where s.studentid = p.personid);
Although you can write this query with left join, I think the version using not exists is almost a direct translation of the question, making it easier to understand.
In Oracle, you can also write this using minus -- if you want only the id:
select personid
from person
minus
select teacherid
from teacher
minus
select studentid
from student;
--Try this with Left Outer Join...
SELECT
P.PersonID,
P.FirstName,
P.LastName,
P.Gender,
P.DateOfBirth
FROM PERSON P
LEFT OUTER JOIN STUDENT S ON P.PersonID = S.StudentID
LEFT OUTER JOIN TEACHER T ON P.PersonID = T.TeacherID
WHERE S.PersonID is null and T.PersonID is null

SQL - listing members on enrolled classes

I am trying to figure out why this isn't working. I am trying to select each member's names and the classes that each member is enrolled on together with the class trainers name.
This is what I have at the minute:
SELECT
firstName, lastName, className, trainerName
FROM
member, _class, trainer, enrolment
WHERE
enrolment.memberID = member.memberID
AND enrolment.classID = _class.classID;
Any help or tips would be appreciated as I am still learning SQL.
Extra info:
enrolment table has columns entrolmentID, memberID and classID
trainer table has columns trainerID and trainerName
member table has memberID, firstName, lastName, age, trainerID
class table has classID, className, _day and trainerID
The valid syntax for a JOIN statement is:
SELECT FIELD1
,...FIELDN
FROM TABLE1 T1
INNER JOIN TABLE2 T2 ON T1.FIELDX = T2.FIELDY
So in your case, use:
SELECT firstName
,lastName
,className
,trainerName
FROM member
INNER JOIN enrolment ON enrolment.memberID = member.memberID
INNER JOIN _class ON enrolment.classID = _class.classID
INNER JOIN trainer ON trainer.trainerID = member.trainerID
Try this
SELECT firstname, lastname, classname, trainerName
FROM member
INNER JOIN enrollment
ON enrolment.memberID = member.memberID
INNER JOIN _class
ON enrollment.classID = class.classID
INNER JOIN trainer
ON trainer.trainerID = member.trainerID

How to write this query to display a COUNT with other fields

I have following two tables:
Person {PersonId, FirstName, LastName,Age .... }
Photo {PhotoId,PersonId, Size, Path}
Obviously, PersonId in the Photo table is an FK referencing the Person table.
I want to write a query to display all the fields of a Person , along with the number of photos he/she has in the Photo table.
A row of the result will looks like
24|Ryan|Smith|28|6
How to write such query in tsql?
Thanks,
You need a subquery in order to avoid having to repeat all the columns from Person in your group by clause.
SELECT
p.PersonId,
p.FirstName,
p.LastName,
p.Age,
coalesce(ph.PhotoCount, 0) as Photocount
FROM
Person p
LEFT OUTER JOIN
(SELECT PersonId,
COUNT(PhotoId) as PhotoCount
FROM Photo
GROUP BY PersonId) ph
ON p.PersonId = ph.PersonId
SELECT
p.PersonId,
p.FirstName,
p.LastName,
p.Age,
CASE WHEN
t.ThePhotoCount IS NULL THEN 0 ELSE t.ThePhotoCount END AS TheCount
--the above line could also use COALESCE
FROM
Person p
LEFT JOIN
(SELECT
PersonId,
COUNT(*) As ThePhotoCount
FROM
Photo
GROUP BY PersonId) t
ON t.PersonId = p.PersonID
SELECT P.PersonId, FirstName, LastName,Age, COUNT(PhotoId) AS Num
FROM Person P
LEFT OUTER JOIN PHOTO PH ON P.PersonId = PH.PersonId
GROUP BY P.PersonId, FirstName, LastName,Age
select Person.*, count(PhotoId) from Person left join Photo on Person.PersonId = Photo.PersonId
IMO GROUP BY should be the solution, something like this works for me even with other table joins:
SELECT meetings.id, meetings.location, meetings.date, COUNT( users.id ) AS attendees
FROM `meetings`
LEFT JOIN users ON meetings.id = users.meeting_id
WHERE meetings.moderator_id = 'XXX'
GROUP BY meetings.id