我需要使用t-sql来查询两个表。第一个表是Books。第二个表是作者。对于每个Book记录,可能有多个子作者记录。我想编写一个查询,只返回为当前Book记录找到的第一个作者记录。表中有数十万条记录,因此我需要查询才能有效。
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个记录。我怎样才能得到我想要的结果?
答案 0 :(得分: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
虽然我觉得作者会成为书籍的孩子似乎很奇怪......:)
答案 1 :(得分: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
答案 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