TSQL Challenge 16 - Solution by Kevin Suchlicki (2)



-- File Name: kevin_suchlicki_tsqlchallenge_16_v2.sql
;WITH DateList AS
(
	SELECT PersonID, StartDate Dt, 0 IsEndDate
	FROM @Membership
	UNION
	SELECT PersonID, EndDate, 1
	FROM @Membership
)
, OrderedDateList as
(
	SELECT	PersonID, Dt, IsEndDate
			, Row_Number() OVER (PARTITION BY PersonID ORDER BY IsNull(Dt, '31/12/9999 23:59:59.997')) ord
	FROM	DateList
)
, DateRanges as
(
	SELECT	o.PersonID
			, CASE WHEN o.IsEndDate = 0 THEN o.Dt ELSE o.Dt + 1 END StartDate
			, Max(CASE WHEN o2.IsEndDate = 1 THEN o2.Dt ELSE o2.Dt - 1 END) EndDate
	FROM	OrderedDateList o
			INNER JOIN OrderedDateList o2 ON o2.PersonID = o.PersonID And o2.ord = o.ord + 1
	WHERE	o.Dt Is Not Null
	GROUP BY o.PersonID
			, CASE WHEN o.IsEndDate = 0 THEN o.Dt ELSE o.Dt + 1 END 
)
, DateRangesWithMembership As
(
	SELECT  d.PersonID
			, Convert(char(10), d.StartDate, 103) StartDate, Convert(char(10), d.EndDate, 103) EndDate
			, Stuff((SELECT ' / ' + m.Description
			FROM	@Membership m
			WHERE	m.PersonID = d.PersonID 
					And d.StartDate >= m.StartDate And (d.StartDate <= m.EndDate Or m.EndDate Is Null)
			ORDER BY m.StartDate
			FOR XML PATH('')), 1, 3, '') Membership
	FROM	DateRanges d
)
SELECT	drm.PersonID, n.Surname, n.FirstName, drm.Membership, drm.StartDate, drm.EndDate
FROM	DateRangesWithMembership drm
		INNER JOIN 
			(SELECT DISTINCT PersonID, Surname, FirstName 
			FROM	@Membership) n ON n.PersonID = drm.PersonID
WHERE	drm.Membership Is Not Null
ORDER BY drm.PersonID, Cast(drm.StartDate As datetime)

Did you find something incorrect/wrong with this solution? Take a few seconds to Report It.

Did you understand how this solution work? If you find it difficult to understand, you can Request an Explanation or you can Write an explanation to help others better understand this solution.