1

我有这些桌子

BooksCatalog
[BookCatalogID],[BooksCatalogBookID],[ReceivedFrom],[BillNo],[billdate]

Books
[BookID],[BookTitle],[ISBN],[ISBN13],[BookAuthorID],[BookPublisherID],[YearPublished],[NumberOfPages],[Volume],[edition],[Price]

Authors
[AuthorID],[AuthorName],[AuthorCityID],[AuthorStateID],[PhoneNumber],[Email],[Website]

我正在运行这个查询,

SELECT Books.BookTitle FROM Books 
        INNER JOIN Authors ON Authors.AuthorId=Books.BookAuthorID
        WHERE Books.BookID IN 
        (SELECT BooksCatalog.BooksCatalogBookID FROM BooksCatalog
        WHERE BooksCatalog.billdate = (SELECT MIN(BooksCatalog.billdate) FROM BooksCatalog))
        AND
        AUTHORS.AuthorName = @AuthorName;

因为它使用了 2 个子查询,所以我感觉它没有优化,如果与等效的内部连接一起使用,它可以表现得更好。那么,这个等效的内部连接是什么?我正在做的是找到添加到库中的第一个给定作者。

4

2 回答 2

2

对于在整个模式中使用别名、模式前缀和将元素(例如 BookId 或 AuthorId)命名为相同的东西,有很多话要说。它真的需要被称为 BookAuthorId 或 BooksCatalogBookID 吗?

无论如何,您的查询可以通过这种方式重新编写得更整洁,但正如@billy 建议的那样,它可能不会真正受益于完全不同的计划:

SELECT b.BookTitle 
FROM dbo.Books AS b 
INNER JOIN Authors AS a 
ON a.AuthorId = b.BookAuthorID
INNER JOIN 
(
  SELECT BookId = MIN(BooksCatalogBookID)
   FROM dbo.BooksCatalog 
) AS bc
ON bc.BookId = b.BookId
WHERE a.AuthorName = @AuthorName;

似乎你在这里依赖一个非常特殊的加入标准。在目录中的所有书籍中,账单日期最早的书籍也恰好是您确定的一位作者所写的几率是多少?您的逻辑是否真的可能是从指定作者那里获得第一本收费书籍?如果是这样,那么也许这更有意义:

;WITH x(BookTitle, rn) AS
(
  SELECT b.BookTitle, ROW_NUMBER() OVER (ORDER BY bc.billdate)
    FROM dbo.BooksCatalog AS bc
    INNER JOIN b.Books AS b
    ON b.BookId = bc.BooksCatalogBookID
    INNER JOIN dbo.Authors AS a
    ON b.BookAuthorID = a.AuthorID
    WHERE a.AuthorName = @AuthorName
)
SELECT BookTitle FROM x WHERE rn = 1; 
于 2012-09-26T03:26:29.757 回答
0

您可以用内部联接替换一个子查询。

            SELECT Books.BookTitle 
              FROM Books 
        INNER JOIN Authors 
                ON Authors.AuthorId = Books.BookAuthorID
        INNER JOIN BooksCatalog 
                ON BooksCatalog.BooksCatalogBookID = Books.BookID 
               AND BooksCatalog.billdate = (SELECT MIN(BooksCatalog.billdate) FROM BooksCatalog) WHERE BooksCatalogBookID = Books.BookID)
        WHERE      Authors.AuthorName = @AuthorName;
于 2012-09-26T03:16:27.760 回答