am trying to run some SQL which needs a PARTITION BY but can't manage to tackle the complexity required. The below data is simplified but the idea is to use the first three columns of the table to find the 4th column (I've added values manually), while also displaying the other columns in the table.
For each customer in the table, it needs to count the number of days that the last enquiry for this customer fell on before the current record's enquiry date as long as it is less than 28 days before otherwise show a NULL. Also need to allow for ties which can be broken via the Enquiry column value being smaller - the smaller value being counted as first.
Customer Enquiry EnquiryDate DaysSinceLastEnquiryForCustomer
522181 232853 19/01/2014 NULL
522181 234750 30/01/2014 11
522181 235141 03/02/2014 4
522181 235210 03/02/2014 4
522181 262015 23/09/2014 NULL
522181 263942 09/10/2014 16
522181 265583 22/10/2014 13
522181 311345 01/10/2015 NULL
522181 321938 31/12/2015 NULL
522181 322404 31/12/2015 0
522181 328057 27/01/2016 23
522181 329164 02/02/2016 6
522181 329426 03/02/2016 1
522181 336409 17/03/2016 14
522181 336581 18/03/2016 1
522181 337003 22/03/2016 4
522181 343338 15/05/2016 NULL
522181 344185 23/05/2016 8
522181 352323 06/08/2016 14
Thanks in advance
Not sure I understand how that logic produces those results. But here's a sample to play with:
Note in SSMS (or VS) if you hold down Shift+Alt and Arrow up/down you get a "vertical selection", into which you can type the same value in multiple columns. So easily turning the above fixed-width table into an INSERT .. VALUES query.
use tempdb
go
drop table if exists C
create table C(Customer int, Enquiry int, EnquiryDate date)
insert into C(Customer,Enquiry,EnquiryDate)
values
--Customer Enquiry EnquiryDate DaysSinceLastEnquiryForCustomer
(522181, 232853,parse('19/01/2014' as date using 'en-GB')),-- NULL
(522181, 234750,parse('30/01/2014' as date using 'en-GB')),-- 11
(522181, 235141,parse('03/02/2014' as date using 'en-GB')),-- 5
(522181, 235210,parse('03/02/2014' as date using 'en-GB')),-- 5
(522181, 262015,parse('23/09/2014' as date using 'en-GB')),-- NULL
(522181, 263942,parse('09/10/2014' as date using 'en-GB')),-- NULL
(522181, 265583,parse('22/10/2014' as date using 'en-GB')),-- 13
(522181, 311345,parse('01/10/2015' as date using 'en-GB')),-- 10
(522181, 321938,parse('31/12/2015' as date using 'en-GB')),-- NULL
(522181, 322404,parse('31/12/2015' as date using 'en-GB')),-- 0
(522181, 328057,parse('27/01/2016' as date using 'en-GB')),-- 23
(522181, 329164,parse('02/02/2016' as date using 'en-GB')),-- 6
(522181, 329426,parse('03/02/2016' as date using 'en-GB')),-- 1
(522181, 336409,parse('17/03/2016' as date using 'en-GB')),-- 14
(522181, 336581,parse('18/03/2016' as date using 'en-GB')),-- 1
(522181, 337003,parse('22/03/2016' as date using 'en-GB')),-- 4
(522181, 343338,parse('15/05/2016' as date using 'en-GB')),-- NULL
(522181, 344185,parse('23/05/2016' as date using 'en-GB')),-- 8
(522181, 352323,parse('06/08/2016' as date using 'en-GB'))-- 14
select *, prev.daysSince
from C c1
outer apply
(
select top 1 *, datediff(day, c2.EnquiryDate, c1.EnquiryDate) daysSince
from C c2
where c2.Customer = c1.Customer
and c2.Enquiry != c1.Enquiry
and c2.EnquiryDate < c1.EnquiryDate
and datediff(day, c2.EnquiryDate, c1.EnquiryDate) < 28
order by c2.EnquiryDate desc
) prev
order by c1.Customer,c1.Enquiry