2012-04-10 40 views
1

2つのテーブルを照会するのにt-sqlを使う必要があります。最初の表はBooksです。 2番目の表は著者です。各ブックレコードには複数の子著者レコードが存在する可能性があります。私は、現在のブックレコードで見つかった最初の著者レコードのみを返すクエリを書きたいと思います。テーブルには何十万ものレコードがあるので、効率的なクエリが必要です。クエリの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

+0

同じBookID – user31673

+0

を持っている限り、選択された著者に使用される基準はありません。あなたのauthorsテーブルにauthorIDフィールドがありますか? – Taryn

答えて

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恐ろしい..... –

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を使用できますが、サブクエリが複数回使用されている場合に役立ちます。そして1つは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 
関連する問題