2016-10-12 5 views
1

Извинения, я надеюсь, что я поставил это в нужное место, но у меня есть несколько вопросов по моей базе данных, которые я не могу понять, почему мои запросы не работают.Oracle SQL Query 2

Моя база данных отношений Схема выглядит следующим образом:

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) Мне нужно найти, если есть какие-либо больше ученых, которые написали менее 20 работ. Мне нужно указать acnum, title, famname, givename и количество написанных им документов. Смотрите мою попытку ниже:

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) Мне также нужно найти отделы с наибольшим количеством ученых и распечатать их столбец DEPTNUM DEPTNAME и InstName, но им получает ошибку синтаксиса. См. Мою попытку:

SELECT deptnum, deptname, instname, count(acnum) 
FROM department, academic, 
WHERE academic.deptnum = department.deptnum 
GROUP BY deptnum 
HAVING MAX(count(acnum)); 
+0

Если я правильно понимаю вашу схему правильно, не должно быть никаких дубликатов в таблица 'author' (конкретный академический должен" t быть показан как автор конкретной статьи более одного раза). Если это так, в первом запросе вам нужно только одно соединение, между «академическим» и «авторским» - вам не нужно присоединяться к таблице «paper». – mathguy

ответ

0

Ваши соединения должны быть в порядке их загрузки.

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; 

Используйте ORDER BY, чтобы дать вам первое отделение.

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); 
+0

Благодарим за это, но все равно получаю синтаксическую ошибку: отсутствует ключевое слово. Есть идеи? –

+0

@ B.Straat попробуйте сейчас – Matt

+0

Второй запрос по-прежнему будет возвращать все отделы, а не только один (или два или три ...) с наибольшим количеством академиков. – mathguy

2

Предполагая пару (panum, acnum) не появляется в author больше, чем когда-то (нет дубликатов в этой таблице), вам не нужно, чтобы присоединиться к paper в первом запросе. Этого должно быть достаточно:

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; 

Ошибка в исходной попытке был порядок on условий; первое внутреннее соединение должно выполняться НЕМЕДЛЕННО по его соответствующему состоянию on, вы не можете оставить его на потом. Однако, как я только что показал, вам нужно только одно соединение.

Для второго запроса вам необходимо сначала найти отдел (ы) с максимальным числом академиков, используя таблицу academic. Затем вы можете присоединиться к результату в таблице department.

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 
; 
0

Вы должны устранить дубликаты или его

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; 

и

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; 

или

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; 
+0

Второй запрос будет работать, но он пропустит «связи» (случаи, когда могут быть два или три отдела, привязанные к наибольшему числу ученых). – mathguy

+0

Спасибо за ваш вопрос. Я добавляю код с dense_rank, чтобы исправить его –