Sql-Server

在不知道會有多少列的情況下,在另一個表的列中顯示一個表的行數

  • May 14, 2022

假設我有一個Library數據庫和以下表格:

  • Books(ID, Title, Author, PublihserID, LanguageCode, Genre, DatePublished, ISBN)- 包含作為抽象項目、智力工作的書籍範例

  • Branches(ID, Name, City, Address)- 包含不同城市的圖書館分館

  • BookCopies(ID, BookID, BranchID, Condition)- 包含作為物理項目的書籍以及它們所在的分支

我想寫一個查詢,它為每一本書Books顯示圖書館的每個分支中有多少本書的物理副本。到目前為止,我在數據庫中的數據有三個帶有ID1和. 我編寫了以下查詢,它正確顯示了我想要的內容(添加了一些額外的內容,例如作者 Agatha Christie 的過濾):2``3

SELECT
   Books.Title,
   Books.PublisherID,
   Books.DatePublished,
   Books.ISBN,
   r1.Branch1,
   r1.Branch2,
   r1.Branch3
FROM
   Books
   JOIN
   (SELECT
       copies.BookID,
       br1.Branch1,
       br2.Branch2,
       br3.Branch3
   FROM
       BookCopies copies
       JOIN
       (SELECT
           BookCopies.BookID,
           COUNT(BookCopies.BranchID) AS Branch1
       FROM
           BookCopies
       GROUP BY BookCopies.BookID, BookCopies.BranchID
       HAVING BookCopies.BranchID=1) br1
       ON copies.BookID=br1.BookID
       FULL JOIN
       (SELECT
           BookCopies.BookID,
           COUNT(BookCopies.BranchID) AS Branch2
       FROM
           BookCopies
       GROUP BY BookCopies.BookID, BookCopies.BranchID
       HAVING BookCopies.BranchID=2) br2
       ON copies.BookID=br2.BookID
       FULL JOIN
       (SELECT
           BookCopies.BookID,
           COUNT(BookCopies.BranchID) AS Branch3
       FROM
           BookCopies
       GROUP BY BookCopies.BookID, BookCopies.BranchID
       HAVING BookCopies.BranchID=3) br3
       ON copies.BookID=br3.BookID
   GROUP BY copies.BookID, br1.Branch1, br2.Branch2, br3.Branch3) r1
   ON Books.ID=r1.BookID
WHERE Books.Author='Agatha Christie'

但是這樣的查詢有兩個基本問題:

  1. 我敢肯定它真的很慢,效率低下並且充滿了不良做法
  2. 它針對三個分支進行了硬編碼。如果圖書館開設第四,第五等分店,它就行不通了。

如何改進我的查詢,使其適用於所有分支(無論它們的數量),並且最好有效地使用資源?

基本上,你沒有。格式化是表示層的一項工作,在數據庫層中,您專注於獲得正確的結果:

SELECT BookID, BranchID, COUNT(*)
FROM BookCopies
GROUP BY BookID, BranchID

為您提供每本書/分支組合的計數。加入書籍和分支機構:

SELECT b.Title
   ,  b.PublisherID
   ,  b.DatePublished
   ,  b.ISBN
   ,  r.Branch
   ,  x.CNT
FROM Books b
JOIN (
   SELECT BookID, BranchID, COUNT(*) AS CNT
   FROM BookCopies
   GROUP BY BookID, BranchID
) AS x
   USING (BookID)
JOIN Branches r
   USING (BranchID)
ORDER BY b.BookID, r.BranchID

在您的應用程序中,您可以遍歷該結果集。當 bookid 更改時,您會在“報告”中創建一個新行。對於每個新的分支,您都會創建一個新列

編輯:SQL 伺服器不支持 USING 子句:

小提琴

SELECT b.ID as BookID
   ,  b.Title
   ,  b.PublisherID
   ,  b.DatePublished
   ,  b.ISBN
   ,  r.ID as BranchID
   ,  r.Name as Branch
   ,  x.CNT
FROM Books AS b
JOIN (
   SELECT BookID, BranchID, COUNT(*) AS CNT
   FROM BookCopies
   GROUP BY BookID, BranchID
) AS x
   ON b.ID = x.BookID
JOIN Branches AS r
   ON r.ID = x.BranchID
ORDER BY b.ID, r.ID;

根據評論,這是一個尋找想法的課程項目。一些可能值得研究的事情是:

STRING_AGG

視窗函式

按匯總、多維數據集、分組集分組

CTE,公用表表達式

臨時表

引用自:https://dba.stackexchange.com/questions/312116