识别自SQL首次创建以来在设定时间范围内重复的记录

时间:2018-05-20 15:12:45

标签: sql sql-server tsql

尝试找出一个可用于查找在首次创建之后在预定义时间范围内重复的记录的查询。

比方说,我想确定在上次购买后的1个月内下订单的客户。

在以下示例中,Tom和Jeff都在重复客户。但只有杰夫符合在一个月内下订单的标准:

Record Customer     Date
1      Tom          6/26/2018
2      Carly        6/31/2018
3      Jeff         7/1/2018
4      Jeff         7/20/2018
5      Tom          8/3/2018

我试图在没有定义实际日期的情况下解决这个问题,因为我希望在第一次在表格中找到记录时设置开始日期。

SQL有没有办法做到这一点?

注意:如果需要说明,请告诉我,英语不是我的第一语言。

4 个答案:

答案 0 :(得分:2)

select Customer,count(1) OrderCount from (
  select distinct T1.* 
  from Table1 T1
  left join Table1 T2 on 
    T1.Record <> T2.Record
    and T1.Customer = T2.Customer 
    and DATEDIFF ( month , T1.[Date] , T2.[Date] ) =0 
  where T2.Record is not null
) T
group by Customer;
| Customer | OrderCount |
|----------|------------|
|     Jeff |          3 |
.hpp

Demo SQL Fiddle

希望它可以帮到你: - )

答案 1 :(得分:1)

有很多方法可以做到,其中一种可能的方法是sefl join。
以下查询列出了在1个月内购买次数超过1次的客户,列出了最早购买日期,计数以及此期间内最后一次购买的日期:

df

答案 2 :(得分:1)

您可以尝试将 Windows功能 CTE 查询一起使用,以使 RowNumber

然后自我加入CTE查询比较第一行和第二行之间的月份差异。

看起来像这样。

;with cte as(
  SELECT *,ROW_NUMBER() OVER(partition by Customer ORDER BY Record) rn
  FROM T 
)
select t1.Customer
from 
cte t1 left join cte t2
ON t1.Record < t2.Record and t1.Customer = t2.Customer 
and t1.rn = 1 and t2.rn = 2
where DATEDIFF( month , t1.[Date] , t2.[Date])=0

sqlfiddle:http://sqlfiddle.com/#!18/01e3b/7

答案 3 :(得分:0)

我相信LAG和LAG的组合DATEADD&amp; IIF(或CASE)也可用于此。
然后,与上一个客户日期相比,每个客户日期获得1或0。

然后可以总结一下。

这是一种不需要自我加入的替代方案。

declare @Table1 table (ID int identity(1,1) primary key, Customer varchar(5), [Date] datetime);

INSERT INTO @Table1 ([Date],Customer) VALUES
('2018-06-26','Tom'),
('2018-07-02','Carly'),
('2018-07-01','Jeff'),
('2018-07-20','Jeff'),
('2018-07-23','Jeff'),
('2018-08-03','Tom');

SELECT Customer, SUM(PreviousDateWithinMonth) as TotalWithinMonth
FROM
(
    SELECT * , IIF(DATEADD(month,1,lag([Date]) OVER (PARTITION BY Customer ORDER BY [Date])) >= [Date],1,0) AS PreviousDateWithinMonth
    FROM @Table1 t1
) q
GROUP BY Customer
HAVING SUM(PreviousDateWithinMonth) > 0
ORDER BY TotalWithinMonth DESC;