1

t-sql を使用して 2 つのテーブルをクエリする必要があります。最初のテーブルは Books です。2 番目のテーブルは Authors です。Book レコードごとに、複数の子 Author レコードが存在する可能性があります。現在の Book レコードで見つかった最初の Author レコードのみを返すクエリを作成したいと考えています。テーブルには何十万ものレコードがあるため、クエリを効率的にする必要があります。

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 に一致する Authors の上位 1 レコードのみを選択したい。探している結果を得るにはどうすればよいですか?

4

3 に答える 3

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

Authors が Books の子になるのは奇妙に思えますが... :)

于 2012-04-10T18:21:12.623 に答える
0

TIMTOWTDIの精神で。

派手なサブクエリであるCTEを使用できますが、サブクエリが複数回使用される場合に役立ちます。そして、ランク関数の 1 つ、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 
于 2012-04-10T19:10:55.473 に答える
0

これがより効率的かどうかを確認してください。min(authorID) を 1 回だけ検索すると、パフォーマンスが向上する場合があります。

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 
于 2012-04-10T18:43:34.787 に答える