2012-02-06 7 views
3

私は購買情報を抽出したいメンバーシップデータベースを持っていますが、SQLで最も良い方法はわかりません。私たちは定期購読を販売しています。定期購読は一定期間、ジムへの入場券です。 3ヶ月。メンバーはそれらを購入し、期限が切れると別のメンバーを買うかもしれません。メンバーのグループを選択したいと思います。しばらく前に3か月のパスを購入した学生は、次回の購読購入があった場合はそれを決定します。SQLでの購入クエリをフォローアップ

関与(関連列を持つ)の3つのテーブルがあります

  • SubscriptionTypesが(ID、説明、期間は) - サブスクリプションが
  • サブスクリプションを購入することができるかを定義(MEMBERID、SubTypeID、開始日、終了日) - 購入のインスタンスは、彼らは時間をかけて購入したサブスクリプションの種類とメンバーをリンク
  • メンバー(ID、タイプ) - メンバデータ、タイプすることができ学生、標準、年金受給者

は、だから私は去年一年のこの時点で3ヶ月のサブスクリプションを購入メンバーのIDを決定したい場合は、私のようなもの使用することができます

SELECT MemberID, StartDate, EndDate 
FROM Subscriptions s 
INNER JOIN Members m 
ON s.MemberID = m.ID 
INNER JOIN SubscriptionTypes st 
ON s.SubTypeID = st.ID 
WHERE s.StartDate BETWEEN <period start> and <period end> 
AND m.Type = 'Student' 
AND st.Duration = 3 

をこれが私のメンバーのセット(となります彼らが昨年買ったパスの実際の開始日と終了日)。

しかし、どのようにしてこの出発点から始めて、3ヶ月の有効期限が切れた後の期間(たとえば1ヶ月)にこれらのメンバーの次回の購読購入を抽出しますか?私は手続きメソッドを思い付くことができます。上のセットの各メンバーを繰り返し実行してクエリを実行しますが、これはSQLの方法ではありません。

誰か私にある方向を教えてもらえますか?私は元のセット、彼らの最初の購読予約情報とその2番目の(もしあれば)メンバーのセットで終了したいと思います。

答えて

0

それは大きいですが、あなたはこのような何かを行うことができます。あなたの選択で

SELECT m.MemberID, s.StartDate, s.EndDate 
FROM Subscriptions s 
INNER JOIN Members m 
ON s.MemberID = m.ID 
INNER JOIN SubscriptionTypes st 
ON s.SubTypeID = st.ID 

INNER JOIN (SELECT m.MemberID, s.EndDate 
FROM Subscriptions s 
INNER JOIN Members m 
ON s.MemberID = m.ID 
INNER JOIN SubscriptionTypes st 
ON s.SubTypeID = st.ID 
WHERE s.StartDate BETWEEN a.EndDate and dateadd('m', 1, a.EndDate) 
AND m.Type = 'Student' 
AND st.Duration = 3) a on a.MemberID = m.MemberID 

WHERE s.StartDate BETWEEN dateadd('m', 4, <period start>) and dateadd('m', 4, <period end>) 
AND m.Type = 'Student' 

が、あなたは別の選択等しいが、内側には、それに参加します。インナー・ジョイントでは、テストしたいメンバーとバウチャーの終了日を取得します。したがって、外部クエリでそのEnddateを使用することができます。

+0

あなたの答えをありがとう。 2つの質問:(a)1行目のn.MemberIDを参照してください。それはm.MemberIDですか? (b)あなたは "a"という2つの列を参照します。接頭辞として "a"はどこに定義されていますか? (c)これは、3ヶ月間のパスを購入する学生は除外しますが、それ以外は何もしません。 2回目の購入者を選択するだけですか? – dave

+0

)はい、編集しました。 b)内部クエリ(私はそれにエイリアスを作った)c)はい、2番目を作ったものだけを選択します。内側のクエリ(エイリアスa)は、パスを購入したメンバを選択し、外側のクエリは、他のメンバを購入したメンバから選択します。 –

2

SQL Server 2005を使用しているため、ROW_NUMBERの権限を利用できます。私は日付の順序を示すシーケンス番号と一緒に、または@PeriodStart後に開始するサブスクリプション、すべてのサブスクリプションの行を持つ各Studentメンバーのために、

SELECT MemberID, StartDate, EndDate, 
    ROW_NUMBER() OVER(PARTITION BY MemberID ORDER BY s.StartDate ASC) 
     AS SubscriptionSequence 
FROM Subscriptions s 
INNER JOIN Members m ON s.MemberID = m.ID 
INNER JOIN SubscriptionTypes st ON s.SubTypeID = st.ID 
WHERE @PeriodStart <= s.StartDate 
AND m.Type = 'Student' 

これはあなたを与えるようなもので始まることをお勧め。

誰かが1ヶ月後、3ヶ月を要した場合、あなたはさらにクエリ絞り込みで、またはアプリケーションコードのいずれかで

TheMemberId Jul 1 2011 Sep 30 2011  1 
TheMemberId Oct 1 2011 Oct 31 2011  2 

を取得したいあなたが望むように、あなたはシーケンス番号を消費することができます。


注記:

概念的な動作はこれです:

  1. (すなわち、特定の日付以降に行われた)
  2. グループにそれらWHERE条件を満たしているすべての購入を識別するメンバー別()
  3. メンバーごとのグループ内で、日付順に購入を注文し、そのポジションに注意してくださいそのグループ内だけ興味があるなら
  4. 注文につき、メンバーのグループ内の位置であるいずれかの列(これはSubscriptionSequenceある)

で、それぞれの購入のための行を放ち(つまりはROW_NUMBER() OVER(... ORDER BY)です) メンバーには、フォローアップの購入を作った、あなたは私が各行の予選subscの数をカウントする列を含める相関サブクエリを使用していた

SELECT MemberID, StartDate, EndDate, 
    ROW_NUMBER() OVER(PARTITION BY MemberID ORDER BY s.StartDate ASC) 
     AS SubscriptionSequence, 
    (SELECT COUNT(*) FROM Subscriptions ss 
        WHERE @PeriodStart <= ss.StartDate 
        AND ss.MemberID = m.ID) AS SubscriptionCount 
FROM Subscriptions s 
INNER JOIN Members m ON s.MemberID = m.ID 
INNER JOIN SubscriptionTypes st ON s.SubTypeID = st.ID 
WHERE @PeriodStart <= s.StartDate 
AND m.Type = 'Student' 
AND SubscriptionCount >= 2 

を行うことができますその行に記載されている会員が作成したものです。メンバーの

出力例は、234と567のID:ここ

234 Jul 1 2011 Sep 30 2011  1  2 
234 Oct 1 2011 Oct 31 2011  2  2 
567 Jul 1 2011 Sep 30 2011  1  3 
567 Oct 1 2011 Oct 31 2011  2  3 
567 Dec 1 2011 Dec 31 2011  3  3 

メンバー567は、これだけの出力には表示されません1つの予選のサブスクリプションを持っていた部材3を持っていたのに対し、部材234は、2つの予選のサブスクリプションを持っていました2番目のクエリは、WHERE句の最後の用語のためです。

+0

答えをありがとう。私はまだそれの周りに私の頭を取得しようとしています。学生が3ヶ月間のパスを購入した場合、その行(つまり、2回目の購入なし)があるかどうかを教えてください。 – dave

+0

少し拡大しました – AakashM

関連する問題