如何为查询编写T-SQL代码

时间:2012-04-10 18:11:33

标签: sql sql-server tsql

我需要使用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个记录。我怎样才能得到我想要的结果?

3 个答案:

答案 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