多个内连接通过排序获得单个记录

时间:2014-10-24 05:58:06

标签: sql sql-server inner-join

我有这样的表格。

Title表:

Book_Title        | ISBN    |Publisher_ID
--------------------------------------
Engineering BK    | 1234556 | 1
Time for a change | 1233333 | 2
Digital Fortress  | 2132312 | 3
Davinci Code      | 2314234 | 3
Angles and Demons | 1232323 | 3

图书ISBN不是普通的ISBN int类型。

Publisher表:

Publisher_ID  | Publisher_Name
--------------------------------
       1      | Crt Books
       2      | NAD Books
       3      | Corg Books

Authorship表:

Author_ID | ISBN
---------------------
   1      |  1232323
   1      |  2314234
   1      |  2314234

Author表:

Author_ID | Author_Name
------------------------
     1    | Dan Brown

Copy表:

   Copy_ID   | ISBN 
-----------------------
      1      | 1234556
      2      | 1233333
      3      | 2132312
      4      | 2314234
      5      | 1232323
      6      | 1232323

Loan表:

Borrower_ID   | Copy_ID | Date_Borrowed |Date_Returned
------------------------------------------------------
     1        |   1     |  2014-10-20   | NULL
     2        |   2     |  2014-10-18   | NULL
     3        |   3     |  2014-10-11   | 2014-10-20
     1        |   4     |  2011-11-11   | 2011-11-25
     2        |   5     |  2010-10-10   | 2010-10-20
     4        |   6     |  2012-12-12   | 2012-12-20

尚未退回的图书的状态被保存为NULL。

我想选择在过去365天内没有借用过一个标题副本的书籍的Title_Names。

我这样实现:

SELECT DISTINCT
   (T.Book_Title) AS BookTitle,
   COUNT(CP.Copy_ID) AS NumberOfCopies,
   MAX (LN.Date_Borrowed) AS LastlyACopyBorrowedDate
FROM Title T INNER JOIN Copy CP ON T.ISBN=CP.ISBN
INNER JOIN Loan LN ON CP.Copy_ID=LN.Copy_ID
INNER JOIN Authorship ASP ON T.ISBN=ASP.ISBN
INNER JOIN Author AT ON ASP.Author_ID=AT.Author_ID
INNER JOIN Publisher PB ON T.Publisher_ID=PB.Publisher_ID
WHERE DATEDIFF(DAY,Date_Borrowed, GETDATE()) > 365
GROUP BY (T.Book_Title);

这很好用。

但是我无法获得标题的Author_Name和Publisher_Name。

当我修改它以获取发布者名称和作者名称时:

SELECT DISTINCT
   (T.Book_Title) AS BookTitle,
   COUNT(CP.Copy_ID) AS NumberOfCopies,
   MAX (LN.Date_Borrowed) AS LastlyACopyBorrowedDate,
   AT.Author_Name,
   PB.Publisher_Name
FROM Title T INNER JOIN Copy CP ON T.ISBN=CP.ISBN
INNER JOIN Loan LN ON CP.Copy_ID=LN.Copy_ID
INNER JOIN Authorship ASP ON T.ISBN=ASP.ISBN
INNER JOIN Author AT ON ASP.Author_ID=AT.Author_ID
INNER JOIN Publisher PB ON T.Publisher_ID=PB.Publisher_ID
WHERE DATEDIFF(DAY,Date_Borrowed, GETDATE()) > 365
GROUP BY (T.Book_Title);

它给我一个错误说:

  

列'Author.Author_Name'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

正如@AA_SC暗示它应该如下:

SELECT
  T.Book_Title AS BookTitle,
  COUNT(CP.Copy_ID) AS NumberOfCopies,
  MAX(LN.Date_Borrowed) AS LastlyACopyBorrowedDate,
  AT.Author_Name,
  PB.Publisher_Name
FROM
  Title T
  INNER JOIN Copy CP ON T.ISBN = CP.ISBN
  INNER JOIN Loan LN ON CP.Copy_ID = LN.Copy_ID
  INNER JOIN Authorship ASP ON T.ISBN = ASP.ISBN
  INNER JOIN Author AT ON ASP.Author_ID = AT.Author_ID
  INNER JOIN Publisher PB ON T.Publisher_ID = PB.Publisher_ID
WHERE
  DATEDIFF(DAY, Date_Borrowed, GETDATE()) > 365
GROUP BY
  T.Book_Title,
  AT.Author_Name,
  PB.Publisher_Name

答案 1 :(得分:1)

您需要将添加内容添加到Group By条款

GROUP BY T.Book_Title, AT.Author_Name, PB.Publisher_Name

请注意,您使用COUNTMAX作为其他列,然后,在其他列中需要GROUP,在这种特定情况下:T.Book_Title, AT.Author_Name, PB.Publisher_Name

您可以阅读更多关于aggregate functions here

的内容