2017-05-17 14 views
2

ValidFromValidToのデータが関連付けられています。T-SQL - 時間の経過に伴う出現の追跡

MembershipId | ValidFromDate | ValidToDate 
========================================== 
0001   | 1997-01-01 | 2006-05-09 
0002   | 1997-01-01 | 2017-05-12 
0003   | 2005-06-02 | 2009-02-07 

このテーブルには、2つの日付をキー値として含む非クラスタ化インデックスがあります。

1900から2999までの日付をすべてカバーする日付ディメンション表もあります。

私はDateディメンションテーブル(2016-01-012016-12-31としましょう)から日付の範囲を選択し、その日に有効なメンバーシップの数を各日付で特定できるかどうかを判断しようとしています。

以下のコードは仕事をしますが、パフォーマンスはあまり良くありません。これについてもっと良い方法をお勧めする人がいますか?

SELECT 
    d.DateKey 
    ,(SELECT COUNT(*) FROM Memberships AS m 
    WHERE d.DateKey between m.ValidFromDateKey and m.ValidToDateKey 
    ) AS MembershipCount 

FROM  
    DIM.[Date] AS d 

WHERE 
    d.CalendarYear = 2016 

ご協力いただきありがとうございます。

答えて

4

SQLのロジックはほとんど正しいですが、SQLのやり方がうまくいかないため、実装したばかりです。あなたがすでに行っているとして、あなたのDatesテーブルで始まるのではなく、サブ選択各行のデータのをやって、joinにあなたのロジックを変更し、あなたがあります

select d.DateKey 
     ,count(m.MembershipID) as MembershipCount 
from DIM.[Date] as d 
    left join Memberships as m 
     on(d.DateKey between m.ValidFromDateKey and m.ValidToDateKey) 
where d.CalendarYear = 2016 
group by d.DateKey 
order by d.DateKey; 

あなたがしたいことは何どのメンバーシップが毎日カウントされるかを特定することに注意してください。たとえば、あなたの日付が2006-05-09の場合、MembershipID 0001はその日に終了する必要がありますか?

アクティブなメンバーシップの数は、のいずれかの時点で、1日中、または特定の時間にアクティブだったメンバー、つまりその日の開始日または終了日をカウントしていますか?

次に、ValidFromDateの値について、この思考プロセスを繰り返します。

+0

素晴らしい!それは完璧に動作します - 私のクエリが30秒を超えると、私はそれを打ち切りましたが、現在は1秒未満で通年を実行します。 日付に関するコメントもありがとうございます。私はメンバーシップが毎日の任意の時点で有効で、ValidTo/Fromの日付が含まれているかどうかを知る必要があるので、あなたの質問にスポットが当てられます。 – triplestones

+0

うわー!これにより必要なパフォーマンスが得られれば、それは良い方法です。非equijoinがあまりにも時間がかかる場合、他のアプローチがあります。 –

+0

@triplestones SQLは一連のデータを使用して動作するため、データのセットを一緒に結合するのに非常に適しています。表は単なるデータの集合です。メインの 'select'の中に別の' select'ステートメントを置くと、一度だけではなく、 'join'されたすべての行に対して実行されます。さらに読むには、 "Set Based Thinking"を参照してください。 – iamdave

関連する問題