Получение этой ошибки в подзапросе: ORA-00934: групповая функция здесь не разрешена - PullRequest
0 голосов
/ 10 февраля 2019

У меня вопрос о том, каково среднее количество книг, опубликованных на автора в базе данных?

примеры данных из категории книг:

TITLE                           CATEGORY
------------------------------ ------------
BODYBUILD IN 10 MINUTES A DAY  FITNESS
REVENGE OF MICKEY              FAMILY LIFE
BUILDING A CAR WITH TOOTHPICKS CHILDREN
DATABASE IMPLEMENTATION        COMPUTER
COOKING WITH MUSHROOMS         COOKING
HOLY GRAIL OF ORACLE           COMPUTER

Я использую эту команду:

select a.lname, a.fname, count(*) "# of Books"
from books b join bookauthor ba using (isbn)
join author a using (authorid)
group by fname, lname;

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

Мой текущий код:

select lname, fname, count(*)
from books 
join bookauthor using (isbn)
join author using (authorid)
where count(*) = (
    select avg(count(*))
    from books
)
group by lname, fname;

Мой ожидаемый результат - получение среднего числа издателей книг на автора, но вместо этого я получаю сообщение об ошибке в строке 4.

Ответы [ 5 ]

0 голосов
/ 11 февраля 2019

вы не можете использовать групповую функцию, такую ​​как count (*), в условии where, которое вы там использовали.В таких сценариях самый простой вариант - использовать предложение «с».

select --- из таблицы, где условия .. группируются по столбцам с количеством (*) = условия ..

0 голосов
/ 10 февраля 2019

Среднее количество книг, опубликованных на автора, является одним числом.Вы можете получить это как:

select count(*) / count(distinct b.authorid)
from bookauthor b;

Если вы хотите это в каждом ряду вместе со счетом:

select a.lname, a.fname, count(*) as num_books,
       avg(count(*)) over () as avg_for_all_authors
from bookauthor ba join
     author a
     using (authorid)
group by a.fname, a.lname
0 голосов
/ 10 февраля 2019

Вы можете переместить существующий запрос в подзапрос и использовать оконную функцию AVG(...) OVER() для вычисления общего среднего значения по автору.

select 
    t.lname, t.fname, t.cnt "# of Books", avg(t.cnt) over() "Avg # of Books"
from (
    select lname, fname, count(*) cnt
    from books
    join bookauthor using (isbn)
    join author using (authorid)
    group by lname, fname, authorid
) t

NB:

  • Я бы порекомендовал префикс столбцов в вашем запросе с правильными псевдонимами таблицы.Четкое представление о происхождении каждого столбца облегчает понимание и обслуживание запроса.

  • Группировка по authorid безопаснее, чем полное имя, поскольку она позволяет избежать ошибочной группировки разных авторов, которыеиметь такое же полное имя.

0 голосов
/ 10 февраля 2019

Без подзапроса это может быть выполнено одним запросом с оконной функцией avg.

select lname, fname, count(*) as "# of Books",avg(count(*)) over() as avg_#_books
from books join bookauthor using (isbn)
join author using (authorid)
group by fname, lname
0 голосов
/ 10 февраля 2019

Вы можете рассчитать количество в подзапросе и добавить среднее значение во внешнем запросе:

select  sub.*, avg("# of Books") over () as "Avg # Books Per Author"
from    (
        select lname, fname, count(*) "# of Books"
        from books join bookauthor using (isbn)
        join author using (authorid)
        group by fname, lname
        ) sub;

Предложение окна over () указывает Oracle рассчитать среднее значение для всех авторов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...