Reputation: 83
Apologies, I hope I have put this in the right place, but I just have a couple of questions re my database which I cannot figure out why my queries aren't working.
My Database Relation Schema is as follows:
DEPARTMENT(deptnum, descrip, instname, deptname, state, postcode)
ACADEMIC(acnum, deptnum*, famname, givename, initials, title)
PAPER(panum, d.)
AUTHOR(panum*, acnum*)
FIELD(fieldnum, id, title)
INTEREST(fieldnum*, acnum*, descrip)
1) I need to find if there are any more academics who have written less than 20 papers. I need to list the acnum, title, famname, givename and number of papers they have written. See my attempt below:
SELECT a.acnum, a.title, a.famname, a.givename, count(p.panum)
FROM ACADEMIC a
INNER JOIN PAPER p
INNER JOIN AUTHOR au ON a.acnum = au.acnum and au.panum = p.panum
GROUP BY a.ACNUM, a.title, a.famname, a.givename
HAVING COUNT(p.panum) < 20;
2) I also need to find the departments with the largest number of academics and print their deptnum, deptname and instname, but im getting a syntax error. See my attempt:
SELECT deptnum, deptname, instname, count(acnum)
FROM department, academic,
WHERE academic.deptnum = department.deptnum
GROUP BY deptnum
HAVING MAX(count(acnum));
Upvotes: 1
Views: 801
Reputation: 1997
Are you need to eliminate duplicates or its
SELECT a.acnum, a.title, a.famname, a.givename, count(au.panum)
FROM ACADEMIC a
JOIN AUTHOR au ON a.acnum = au.acnum
GROUP BY a.ACNUM, a.title, a.famname, a.givename
HAVING COUNT(au.panum) < 20;
and
SELECT deptnum, deptname, instname, count_ac
FROM (
SELECT d.deptnum, d.deptname, d.instname, COUNT(a.acnum) as COUNT_AC
FROM department d
JOIN academic a d.deptnum = a.deptnum
GROUP BY d.deptnum, d.deptname, d.instname
ORDER BY COUNT(a.acnum)
) WHERE ROWNUM < 2;
or
SELECT deptnum, deptname, instname, count_ac
FROM (
SELECT d.deptnum, d.deptname, d.instname, dense_rank() over (order by COUNT(a.acnum) desc) cur_rank, COUNT(a.acnum) as count_ac
FROM department d
JOIN academic a d.deptnum = a.deptnum
GROUP BY d.deptnum, d.deptname, d.instname
) WHERE cur_rank = 1;
Upvotes: 0
Reputation:
Assuming a pair (panum, acnum)
doesn't appear in author
more than once (there are no duplicates in that table), you don't need to join to paper
in the first query. This should suffice:
SELECT a.acnum, a.title, a.famname, a.givename, count(au.panum) as ct
FROM ACADEMIC a
INNER JOIN AUTHOR au ON a.acnum = au.acnum
GROUP BY a.ACNUM, a.title, a.famname, a.givename
HAVING COUNT(au.panum) < 20;
The error in your original attempt was the order of the on
conditions; the first inner join must be followed IMMEDIATELY by its corresponding on
condition, you can't leave it for later. However, as I just showed, you only need one join.
For the second query, you need to find the department(s) with the max number of academics first, using the academic
table. Then you can join the result to the department
table.
select d.deptnum, d.deptname, d.instname, m.ct
from department d inner join
( select deptnum, count(acnum) as ct
from academic
group by deptnum
having count(acnum) = (select max(acnum) from academic group by deptnum)
) m
on d.deptnum = m.deptnum
;
Upvotes: 2
Reputation: 15061
Your joins need to be in order that they load.
SELECT a.acnum, a.title, a.famname, a.givename, COUNT(p.panum)
FROM ACADEMIC a
INNER JOIN AUTHOR au ON a.acnum = au.acnum
INNER JOIN PAPER p ON au.panum = p.panum
GROUP BY a.ACNUM, a.title, a.famname, a.givename
HAVING COUNT(p.panum) < 20;
Use an ORDER BY
to give you the top department.
SELECT d.deptnum, d.deptname, d.instname, COUNT(a.acnum)
FROM department d
INNER JOIN academic a d.deptnum = a.deptnum
GROUP BY d.deptnum, d.deptname, d.instname
ORDER BY COUNT(a.acnum);
Upvotes: 0