To start I am using SSMS 2018. I am trying to create a Common Table Expression to use in some code later. I need to get down to a single row per applicable quarter per person, I’ve tried using Havings/Group Bys and wheres but I can’t get the correct result set. What I have Currently is a table like this:
Total Cookies(DurableKey(Int), QuarterEndDateOfStartQuarter(Date), QuarterEndDate(Date), totalCookies (Int), NumberofDays(Int))
The Durable Key represents a person overtime.
The QuarterEndDateOfStartQuarter represents the first applicable quarter per some requirements, i.e. ate at least 10 cookies in one day during the quarter
The QuarterEndDate represents the current Quarter, up to 3 quarters after the QuarterEndDateOfStartQuarter
The TotalCookies represents the cookies since the beginning of the Start Quarter that have been eaten
The NumberofDays represents the number of days since the beginning of the Start Quarter that a cookie was eaten.
The data looks similar to this:
DurableKey QuarterEndDateOfStartQuarter QuarterEndDate totalCookies NumberofDays 99999 2018-06-30 2018-06-30 1410.000 17 99999 2018-06-30 2018-09-30 6564.000 91 99999 2018-06-30 2018-12-31 8174.000 154 99999 2018-06-30 2019-03-31 9554.000 161 99999 2018-09-30 2018-09-30 5154.000 74 99999 2018-09-30 2018-12-31 6764.000 137 99999 2018-09-30 2019-03-31 8144.000 144 99999 2018-09-30 2019-06-30 10091.000 188 99999 2019-03-31 2019-03-31 1380.000 7 99999 2019-03-31 2019-06-30 3327.000 51 99999 2019-03-31 2019-09-30 3357.000 52 99999 2019-03-31 2019-12-31 3357.000 52 99999 2019-06-30 2019-06-30 1695.000 30 99999 2019-06-30 2019-09-30 1725.000 31 99999 2019-06-30 2019-12-31 1725.000 31 99999 2019-06-30 2020-03-31 2917.500 74
And what I want to end up with is a CTE that has person – quarter granularity rather than person – Start Quarter – quarter. So the table would have the columns :
Cookies(DurableKey(Int), QuarterEndDate(Date), totalCookies (Int), NumberofDays(Int))
Where if there are overlapping rows, the data would be pulled from the row corresponding to the earlier QuarterEndDateOfStartQuarter :
DurableKey QuarterEndDate totalCookies NumberofDays 99999 2018-06-30 1410.000 17 99999 2018-09-30 6564.000 91 99999 2018-12-31 8174.000 154 99999 2019-03-31 9554.000 161 99999 2019-06-30 10091.000 188 99999 2019-09-30 3357.000 52 99999 2019-12-31 3357.000 52 99999 2020-03-31 2917.500 74
I feel like this should be straightforward but have been not been able to accomplish it.
Advertisement
Answer
Use row_number
to order by the QuarterEndDateOfStartQuarter column partitioned by the key and the quarter. Then select the first ordered for each partition.
select DurableKey, QuarterEndDateDate, totalCookies, NumberofDays from ( select *, ord = row_number() over( partition by durableKey, quarterEndDateDate order by QuarterEndDateOfStartQuarter ) from @totalCookies ) tk where ord = 1