SQL ORACLE - 复杂查询

SQL ORACLE - complicated query

我有这样的表:

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

我需要为每个作者找到他的每本书中使用的主题,这些主题是他自己写的,并且没有在他合着的任何书中使用。抱歉我的英语不好。

我能理解为什么您可能不知道从哪里开始。我发现在这种情况下,最好从小处着手,然后使用子查询解决问题。

查找给定作者不是唯一作者的书籍:

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;

然后你可以使用 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;

我同意 David 的观点,从基础开始比继续添加查询以获得所需的答案要容易得多。如果我理解这个问题,您正在寻找主题不属于他们合着的书的所有书籍...

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