2015-01-24 2 views
-2

у меня есть такие таблицы:SQL ORACLE - сложный запрос

Author(name,surname,id_author) 
Author_book(id_author, id_book) 
Book_theme(id_book,id_theme) 
Theme(id_theme, description) 

мне нужно найти для каждой темы автора, который был использован в каждой своей книге, которая была написана им самим и не был использован ни в одной книге, где он был соавтором. Извините за мой бедный английский.

+0

вы пытались что-то? если да, покажите нам, если PLZ не попробует немного, прежде чем спросить – jfun

ответ

0

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

Чтобы найти книги, где данный автор не является единственным автор:

SELECT id_author, id_book 
    FROM (
    SELECT id_author, id_book, COUNT(*) OVER (PARTITION BY id_book) AS author_cnt 
     FROM author_book 
) WHERE author_cnt >= 2; 

Чтобы получить Темы из вышеупомянутых книг:

SELECT ab2.id_author, bt.id_theme 
    FROM (
    SELECT id_author, id_book, COUNT(*) OVER (PARTITION BY id_book) AS author_cnt 
     FROM author_book 
) ab2, book_theme bt 
WHERE ab2.author_cnt >= 2 
    AND ab2.id_book = bt.id_book; 

Вы можете сделать то же самое для книг где автор является единственным автором:

SELECT ab1.id_author, bt.id_theme 
    FROM (
    SELECT id_author, id_book, COUNT(*) OVER (PARTITION BY id_book) AS author_cnt 
     FROM author_book 
) ab1, book_theme bt 
WHERE ab1.author_cnt = 1 
    AND ab1.id_book = bt.id_book; 

T курица вы можете использовать MINUS, чтобы получить набор тем, где автор является единственным автором книги, но не те, где он является соавтором:

SELECT ab1.id_author, bt.id_theme 
    FROM (
    SELECT id_author, id_book, COUNT(*) OVER (PARTITION BY id_book) AS author_cnt 
     FROM author_book 
) ab1, book_theme bt 
WHERE ab1.author_cnt = 1 
    AND ab1.id_book = bt.id_book 
MINUS 
SELECT ab2.id_author, bt.id_theme 
    FROM (
    SELECT id_author, id_book, COUNT(*) OVER (PARTITION BY id_book) AS author_cnt 
     FROM author_book 
) ab2, book_theme bt 
WHERE ab2.author_cnt >= 2 
    AND ab2.id_book = bt.id_book; 
1

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

select name, Author_book.id_book, Theme.id_theme, description 
from Author 
join Author_book on (Author.id_author = Author_book.id_author) 
join Book_theme on (Author_book.id_book = Book_theme.id_book) 
join Theme on (Book_theme.id_theme = Theme.id_theme) 
where name = 'Bob' 
and Book_theme.id_theme not in(select c.id_theme 
           from Author_book b 
           join Book_theme c on (b.id_book = c.id_book) 
           where 
           Author_book.id_book = b.id_book 
           and Author.id_author <> b.id_author) 

SQL Fiddle Example