【问题标题】:How to filter query based on table where they dont share a field?如何根据不共享字段的表过滤查询?
【发布时间】:2020-12-24 20:42:04
【问题描述】:

好的,所以我一直在研究这个 SQL 语句,只是想不通。我需要能够看到客户在 2017 年借用的前 5 位作者。我的表格看起来像这样

1. Client - fields (clientId,clientFirstName,clientlastName,clidentDoB)
2.author - fields (AuthorID, AuthorFirstname, AuthorLastname,AuthorNation )
3. book - fields (BookId, BookAuthor,BookTitle,BookGenre)
4. borrower - fields (borrowID,BorrowDate, ClientID,BookId)

所以我知道我需要从作者表中提取姓名,根据借阅的书籍数量,我也知道borrower.bookId 等于 book.BookId 和 Author.AuthorID 等于 Book.BookAuthor。 我应该能够对其进行设置,以便它看到 2017 年借来的书籍,然后通过使用 borrowBookId 并将相同 Id 的每个实例添加在一起并查看 bookID 与 book 表中的 BookAuthor 匹配,然后使用它来比较用于打印名字和姓氏的 ID。

我试过了

SELECT author.authorfirstname,author.authorlastname 
FROM author Join ON author.authorid = book.bookauthor   
WHERE (borrower.borrowdate <='31/12/2017' AND borrower.borrowdate >= '01/01/2017'); 

我知道这行不通,但我不确定如何搭建从作者到借款人的桥梁。

样本数据及其预期输出。

确定。假设我有 4 位作者,我们想要前 3 位。我们也只有 2017 年的借阅。客户端表并不是真正需要的,所以让我们用一些数据填充其他表。与原始问题示例中相同的表字段名称将是
作者表

(1,bob,ross, USA) 
(2, fred, martin, USA) 
(3, alex,joe,CAN)
(4, dan, reed, can)                          

书桌

(1,1,bobsbook,fantasy) 
(2,1,bobagain,fantasy) 
(3,1,returnofbob,fantasy)
 (4,2,fredsadventure,fantasy) 
(5, 2, fedagain, fantasy) 
(6, 2, fedstrikes, fantasy) 
(7,3,alexjoes, fantasy)
 (8, 3, alexjoeagain,fantasy)
(9,4, dansbook, fantasy)

借表

(1, 20/01/2017,,1, 1)
(2, 20/01/2017,,3, 2)
(3, 20/01/2017,,2, 1)
(4, 20/01/2017,,1, 3)
(5, 20/01/2017,,6, 2)
(6, 20/01/2017,,8, 4)
(7, 20/01/2017,,4, 4)
(8, 20/01/2017,,9, 6)
(9, 20/01/2017,,2, 7)
(10, 20/01/2017,,3, 9)
(11, 20/01/2017,,4, 9)

最终结果是

AuthorFirstName  AuthorLastname 
bob               ross
Fred              Martin
Dan               Reed 

这是因为他们在 2017 年日期范围内的借阅次数最多,依次为 bob 5、fred 3 和 dan 2。它也只打印前 3 人,因此 alex joe 被排除在列表之外。

@fahmi 给出的代码

SELECT author.authorfirstname,author.authorlastname 
FROM author 
Join book ON author.authorid = book.bookauthor
join borrower on book.bookid=borrower.bookid
WHERE borrower.borrowdate <='31/12/2017' AND borrower.borrowdate >= '01/01/2017'

;

这给了我一个作者列表,它列出了洞穴的每个实例,但我需要合并列表,所以我只看到一个名字,这样它就可以被大多数借用和自我限制。

【问题讨论】:

  • 请用版本标记你的数据库。您尝试并提供的代码不完整,您可能想查看一下。提供一些示例数据和预期输出,这将有助于更快地扩展帮助。

标签: sql oracle-sqldeveloper oracle-xe-18.4


【解决方案1】:

使用 Oracle 的 TOP-N 查询功能,

select au.authorfirstname
      ,au.authorlastname 
  from author au
  join book bk
    on au.authorid = bk.bookauthor
  join borrower bw
    on bk.bookid=bw.bookid
 where extract(year from bw.borrowdate) 
       = 2017
group by au.authorfirstname
        ,au.authorlastname
order by count(bk.bookid) desc
fetch first 3 rows with ties;

【讨论】:

    【解决方案2】:

    您需要另一个加入到具有book.bookid=borrower.bookid 关系的借款人

    SELECT top 3 author.authorfirstname,author.authorlastname,count(borrower.bookid) as cnt
    FROM author 
    Join book ON author.authorid = book.bookauthor
    join borrower on book.bookid=borrower.bookid
    WHERE borrower.borrowdate <='31/12/2017' AND borrower.borrowdate >= '01/01/2017'
    group by author.authorfirstname,author.authorlastname
    order by cnt desc
    

    【讨论】:

    • 这对我有很大帮助,我没想过像那样使用第二个加入。因此,这给了我一个名称列表,我需要将它们组合起来,并按数量最多的作者对它们进行排序。我尝试添加 GROUB BY author.authorfirstname , author.authorlastname 按 count(author.authorlastname) 排序,这样我就可以知道前 5 位作者?
    • @Comradedrago,您能否在问题中添加示例数据和您想要的结果。它将帮助人们了解您的要求
    • 我在原始问题中添加了一些示例代码和预期输出。
    • @Comradedrago,我已经更新了我的答案 - 你可以看看
    猜你喜欢
    • 2016-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 2011-08-30
    • 2020-12-19
    相关资源
    最近更新 更多