简体   繁体   中英

SQL query to find the faculty which have taught every subject

I need to write a SQL query to find the faculty which has taught every subject (ie Sam)

  1. With nested queries
  2. Without using aggregate functions (no count, avg, min etc).

I can't seem to figure this out, would really appreciate some help =)

Faculty

fid fname fqualifications fexperience salary deptname
100 Sam ME CS 10 100000 IT
101 John ME IT 8 80000 IT
102 Max ME CS 9 90000 CS
103 Jenny ME CS 5 50000 CS

Course

cid cname semester
1 SE 4
2 WT 4
3 CG 5
4 DBMS 5

Teaches

fid cid year
100 1 2019
100 2 2018
100 3 2020
100 4 2021
101 1 2017
101 2 2018
102 2 2018
102 3 2019
103 3 2020
103 4 2021

I used this query to find the output but according to the question I can't.

select * from faculty f
    -> inner join teaches t
    -> on f.fid=t.fid
    -> inner join course c
    -> on t.cid=c.cid
    -> group by f.fid,f.fname
    -> having count(*)=4;

OUTPUT:

fid fname fqualifications fexperience salary deptname fid cid year cid cname semester
100 Sam ME CS 10 100000 IT 100 1 2019 1 SE 4

Not the most efficient way to proceed, but with the requirements given to you, I would try and rephrase the query like this:

"A faculty that has taught every subject is a faculty that has not skipped even one subject".

Now, faculties that have skipped a subject will have a NULL when LEFT JOINed with the syllabus and all the subjects. Pseudo-SQL:

SELECT DISTINCT faculty.id FROM faculties 
    LEFT JOIN has_taught ON (has_taught.faculty_id = faculty.id)
    LEFT JOIN subjects ON (has_taught.subject_id = subjects.id)
    WHERE has_taught.faculty_id IS NULL;

or in some databases you maybe need

SELECT DISTINCT faculty.id FROM faculties 
    CROSS JOIN subjects
    LEFT JOIN has_taught ON 
      (has_taught.faculty_id = faculty.id AND has_taught.subject_id = subjects.id)
    WHERE has_taught.faculty_id IS NULL;

So, faculties that are NOT IN this list would naturally be

SELECT * FROM faculties
    WHERE faculty.id NOT IN (
        SELECT DISTINCT faculty.id ...
    );

and this should only use nested queries, as requested.

Or with a further join

SELECT faculties.* FROM faculties
    LEFT JOIN (
        SELECT DISTINCT faculty.id ...
    ) AS they_skipped_some
    ON (they_skipped_some.id = faculties.id)
    WHERE they_skipped_some.id IS NULL

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM