仅借用指定作者和编辑的所有书籍的借款人

时间:2019-07-16 09:16:47

标签: sql oracle

对于给定的作者和编辑,我需要列出“仅”“全部”借用该作者和编辑的书的借款人的姓名

  • 成员(主键,名称,生日)
  • 作者(作者代码主键,名称)
  • EDITOR(edcode主键,名称)
  • 借用(出价主键,copyid,mid)
  • COPIES(副本主键,bookid)
  • 书(书夹主键,标题,主题代码)
  • THEME(主题代码主键,标签)

我尝试了以下操作:

SELECT m.name
FROM  MEMBER m,COPIES c,BORROW b1,BOOK b,AUTHOR a,EDITOR e,WRITE w
WHERE m.mid=b1.mid AND b1.copyid=c.copyid AND c.bookid=b.bookid AND b.editor=e.edcode AND a.authorcode=w.author AND w.book=b.bookid 
MINUS
(SELECT m.name
FROM  MEMBER m,COPIES c,BORROW b1,BOOK b,AUTHOR a,EDITOR e,WRITE w
WHERE m.mid=b1.mid AND b1.copyid=c.copyid AND c.bookid=b.bookid AND b.editor=e.edcode AND a.authorcode=w.author AND w.book=b.bookid AND (a.authorcode<>:P58_AUTHOR OR e.edcode<>:P58_EDITOR)    
)

这给了我一个成员,他借了至少一本书,却没有借那个作者和编辑以外的任何书,所以我需要确保他借了所有的书

3 个答案:

答案 0 :(得分:3)

我认为以下内容将为您提供所需的东西:

WITH book_ed_auth_dets AS (SELECT b.bookid,
                                  a.authorcode,
                                  e.edcode,
                                  COUNT(*) OVER (PARTITION BY a.authorcode, e.edcode) tot_num_bks_per_auth_ed
                           FROM   book b
                                  INNER JOIN WRITE w ON b.bookid = w.book
                                  INNER JOIN author a ON w.author = a.authorcode
                                  INNER JOIN editor e ON b.editor = e.edcode
                           WHERE  a.authorcode = :p58_author
                           AND    e.edcode = :p58_editor)
SELECT m.name
FROM   MEMBER m
       INNER JOIN borrow b1 ON m.mid = b1.mid
       INNER JOIN copies ON c.bookid ON b1.copyid = c.copyid
       INNER JOIN book_ed_auth_dets bead ON c.bookid = bead.bookid
GROUP BY m.id,
         m.name,
         bead.authorcode,
         bead.edcode
         bead.tot_num_bks_per_auth_ed
HAVING   COUNT(DISTINCT bead.bookid) = bead.tot_num_bks_per_auth_ed);

未经测试,因为您未提供要使用的示例数据。

这将查找给定作者和编辑者的书籍,并使用分析计数为每一行写出该作者和编辑者的书籍总数。

然后,我们将成员的借阅书与之进行内部连接,找到不同的bookid的数量(以防该成员多次借阅同一本书的情况),并且仅在该数量与作者和编辑者的图书数匹配时才报告成员

答案 1 :(得分:1)

如果我没记错的话,WRITE表是您最难描述的最不推荐的表。

我从您现有的查询中得出了一个主意,并尝试如下创建解决方案:

SELECT
    NAME
FROM
    (
        SELECT
            M.NAME,
            -- NO OF BOOK BORROWED BY MEMBER OF THAT AUTHOR AND EDITOR
            COUNT(DISTINCT B.BOOKID) NO_BOOKS_BORROWED 
        FROM
            MEMBER M
            JOIN BORROW B1 ON ( M.MID = B1.MID )
            JOIN COPIES C ON ( B1.COPYID = C.COPYID )
            JOIN BOOK B ON ( C.BOOKID = B.BOOKID )
            JOIN EDITOR E ON ( B.EDITOR = E.EDCODE )
            JOIN WRITE W ON ( A.AUTHORCODE = W.AUTHOR )
            JOIN AUTHOR A ON ( W.BOOK = B.BOOKID )
        GROUP BY
            M.NAME
        --CONDITION TO CHECK THAT BORROWER HAS NOT BOUGHT ANY OTHER BOOK
        HAVING 
            SUM(CASE
                WHEN A.AUTHORCODE <> :P58_AUTHOR
                     OR E.EDCODE <> :P58_EDITOR THEN 1
            END) = 0
    ) BORRROWER
    --
    JOIN (
        SELECT
            -- NO OF ALL BOOKS WRITTEN BY AUTHOR AND EDITOR
            COUNT(DISTINCT B.BOOKID) NO_BOOKS_WRITTEN
        FROM
            EDITOR E
            JOIN WRITE W ON ( A.AUTHORCODE = W.AUTHOR )
            JOIN AUTHOR A ON ( W.BOOK = B.BOOKID )
        WHERE
            A.AUTHORCODE = :P58_AUTHOR
            AND E.EDCODE = :P58_EDITOR
    ) AUTHOR_EDITOR ON ( BORRROWER.NO_BOOKS_BORROWED = AUTHOR_EDITOR.NO_BOOKS_WRITTEN )

干杯!

答案 2 :(得分:1)

以下内容返回给定作者和编辑者的所有书籍:

select w.bookid
from book b join
     writes w 
     on b.bookid = w.bookid
where b.edcode = :P58_EDITOR and
      w.authorcode = :P58_AUTHOR;

以下内容查找借用了所有这些书籍的成员:

with bae as (
      select w.bookid
      from book b join
           writes w 
           on b.bookid = w.bookid
      where b.edcode = :P58_EDITOR and
            w.authorcode = :P58_AUTHOR 
     )
select b.mid
from borrow b join
     copies c
     on c.copyid = b.copyid join
     bae
     on b.bookid = bae.bookid
group by b.mid
having count(distinct b.bookid) = (select count(*) from bae);

请注意,count(distinct)是必需的,因为一个成员可能可以借用同一本书两次。