Поскольку вы работаете с SQL Server 2005, у вас есть возможности ROW_NUMBER
.Я бы предложил начать с чего-то вроде
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'
. Это даст вам, для каждого Student
участника, у которого подписка начинается с или после @PeriodStart
, строку для каждой подписки.вместе с порядковым номером, указывающим порядок даты.
Так, если кто-то взял 3 месяца, а затем 1 месяц, вы получите
TheMemberId Jul 1 2011 Sep 30 2011 1
TheMemberId Oct 1 2011 Oct 31 2011 2
Либо в дальнейшем уточнении запроса,или в коде приложения вы можете использовать порядковый номер по своему желанию.
Пояснительные примечания:
Концептуальное поведение таково:
- Определить всепокупки, которые удовлетворяют условию
WHERE
(т. е. были сделаны после определенной даты) - Сгруппируйте их по участнику (это
PARTITION BY
) - В пределах каждой группы на каждого участника заказпокупки по дате, и отметьте позицию в этой группе (это
ROW_NUMBER() OVER( ... ORDER BY )
) - Создать строку для каждой покупки, при этом один из столбцов будет позицией в пределах заказанной группы для каждого участника (это
SubscriptionSequence
)
Если выЗаинтересованы только в участниках, которые сделали совершившую последующую покупку, вы можете сделать
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:
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
Здесь член 234 имел две подходящие подписки, тогда как член 567 имел 3. Участник, у которого была только одна подходящая подписка, не появлялся бы ввывод этого второго запроса из-за последнего термина в предложении WHERE
.