2012-04-10 40 views
1

我需要使用t-sql來查詢兩個表。第一張桌子是Books。第二張表是作者。對於每本書籍記錄,可能有多個子作者記錄。我想編寫一個查詢,該查詢僅返回爲當前Book記錄找到的第一個作者記錄。表中有成千上萬的記錄,所以我需要查詢的效率。如何爲查詢編寫T-SQL代碼

select a.FirstName, a.LastName, b.BookName 
from Books b 
left join 
(
    select TOP 1 t.BookID, t.FirstName, t.LastName 
    from Authors t 
) a 
    on a.BookID = b.BookID 
where b.BookClassification = 2 

此查詢結果不正確。我只想選擇與BookID匹配的作者中最高的1條記錄。我怎樣才能得到我期待的結果?

+3

'TOP 1'按什麼標準?隨機?按字母順序排列? – JNK 2012-04-10 18:13:41

+0

只要具有相同的BookID,就不需要使用任何作者標準 – user31673 2012-04-10 18:15:04

+0

您的authors表中是否有authorID字段? – Taryn 2012-04-10 18:16:50

回答

6

你接近:

select a.FirstName, a.LastName, b.BookName 
from Books b 
outer apply 
(
    select TOP 1 t.BookID, t.FirstName, t.LastName 
    from Authors t 
    WHERE t.BookID = b.BookID 
    -- uncomment the next line to control which author to prefer 
    -- ORDER BY t.<someColumn>... 
) a 
where b.BookClassification = 2 

雖然它似乎很奇怪,我認爲作者將圖書的孩子... :)

+0

+1真棒..... – 2012-04-10 18:22:46

0

看看這是更有效的。通過查找min(authorID),只要您可以獲得更好的性能。

select author.FirstName, author.LastName, author.BookName  
from Books with (nolock) 
join 
( select min(authorID) as authorID, bookID 
    from Authors with (nolock) 
    group by bookID 
) as Author1 
    on Author1.authorID = Books.authorID 
join Authors with (no lock) 
on Authors.authorID = Author1.authorID 
and Authors.bookID = Author1.bookID 
where Books.BookClassification = 2 
0

本着TIMTOWTDI的精神。

您可以使用一個花式子查詢CTE,但如果子查詢不止一次使用,它會很有幫助。和一個rank functions,row_number()。

with bookAuthors as ( 
    select a.FirstName, a.LastName, b.BookName, BookClassification, 
    row_number() over(partition by b.BookName order by a.lastName) as rank 
    from Books b 
    left join Authors a 
    on a.BookID = b.BookID 

) 

select a.FirstName, a.LastName, b.BookName 
from bookAuthors 
where rank = 1 
    and BookClassification = 2