SQLフィドル:http ://sqlfiddle.com/#!3 / 9b459 / 6
「このイベントに参加しますか?」という質問に対する回答を含む表があります。各ユーザーは数回応答する可能性があり、すべての回答がテーブルに保存されます。通常、私たちは最新の回答にのみ関心があり、そのための効率的なクエリを構築しようとしています。SQL Server2008R2を使用しています。
1つのイベントのテーブルの内容:
Column types: int, int, datetime, bit
Primary key: (EventId, MemberId, Timestamp)
メンバー18が最初に「いいえ」と答えてから「はい」と答え、メンバー20が最初に「はい」と答えてから「いいえ」と答え、メンバー11が「いいえ」と答えてから「いいえ」と答えたことに注意してください。これらのメンバーの最初の回答を除外したいと思います。また、フィルタリングする必要のある回答が複数ある場合もあります。たとえば、ユーザーは「はい」、「はい」、「いいえ」、「はい」、「いいえ」、「いいえ」、「いいえ」と答える場合があります。
いくつかの異なるアイデアを試し、SQL Server Management Studioですべてのクエリを入力し、[推定実行プランの表示]を選択して、各クエリの合計コストをパーセントで比較することにより、それらを評価しました。それはパフォーマンスを評価するための良い方法ですか?
これまでにテストされたさまざまなクエリ:
-----------------------------------------------------------------
-- Subquery to select Answer (does not include Timestamp)
-- Cost: 63 %
-----------------------------------------------------------------
select distinct a.EventId, a.MemberId,
(
select top 1 Answer
from Attendees
where EventId = a.EventId
and MemberId = a.MemberId
order by Timestamp desc
) as Answer
from Attendees a
where a.EventId = 68
-----------------------------------------------------------------
-- Where with subquery to find max(Timestamp)
-- Cost: 13 %
-----------------------------------------------------------------
select a.EventId, a.MemberId, a.Timestamp, a.Answer
from Attendees a
where a.EventId = 68
and a.Timestamp =
(
select max(Timestamp)
from Attendees
where EventId = a.EventId
and MemberId = a.MemberId
)
order by a.TimeStamp;
-----------------------------------------------------------------
-- Group by to find max(Timestamp)
-- Subquery to select Answer matching max(Timestamp)
-- Cost: 23 %
-----------------------------------------------------------------
select a.EventId, a.MemberId, max(a.Timestamp),
(
select top 1 Answer
from Attendees
where EventId = a.EventId
and MemberId = a.MemberId
and Timestamp = max(a.Timestamp)
) as Answer
from Attendees a
where a.EventId = 68
group by a.EventId, a.MemberId
order by max(a.TimeStamp);
メンバーごとにサブクエリを使用しないようにすると便利です。最後のクエリで使用しようとしgroup by
ましたが、Answer列にサブクエリを使用する必要がありました。私は本当にこのようなものが欲しいのですが、それはもちろん有効なSQLではありません:
select a.EventId, a.MemberId, max(a.Timestamp), a.Answer <-- Picked from the line selected by max(a.Timestamp)
from Attendees a
where a.EventId = 68
group by a.EventId, a.MemberId
order by max(a.TimeStamp);
効率的なクエリのための他のアイデアはありますか?
編集:
SQL Fiddleに非常に感銘を受け、実際のデータをここに入力しました: http ://sqlfiddle.com/#!3/9b459/6