0

我正在尝试运行一些需要 PARTITION BY 但无法解决所需复杂性的 SQL。下面的数据被简化了,但想法是使用表格的前三列来找到第四列(我已经手动添加了值),同时还显示了表格中的其他列。

对于表中的每一个客户,只要在当前记录的查询日期之前小于28天,就需要统计该客户最后一次查询的天数,否则显示为NULL。还需要考虑可以通过更小的查询列值来打破的关系 - 较小的值被计为第一个。

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

提前致谢

4

1 回答 1

0

不确定我是否理解该逻辑如何产生这些结果。但这里有一个示例:

请注意,在 SSMS(或 VS)中,如果您按住 Shift+Alt 和向上/向下箭头,您将获得“垂直选择”,您可以在其中在多列中键入相同的值。如此轻松地将上述固定宽度表转换为 INSERT .. VALUES 查询。

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
于 2018-07-24T16:41:54.657 回答