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)
我有这样的表:
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)