SQL:如何从变化的循环中获取结果

时间:2017-02-16 09:12:44

标签: sql stored-procedures views

要求:如果客户在31天内访问过多次,则仅包括首次访问。例如,如果客户在1月1日访问,则包括1月1日访问,不包括1月2日至1月31日期间或之间发生的访问;然后,如果适用,包括在2月1日或之后发生的下次访问。按时间顺序确定访问次数,包括每31天一次访问次数。

CustomerID  VisitID VisitDate
1              1    1/1/2016
1              2    1/2/2016
1              3    1/31/2016
1              4    2/1/2016
1              5    7/1/2016

我需要在31天内为客户提供第一个条目,因此在上述情况下,我的结果查询应该只显示两个条目

CustomerID  VisitID VisitDate
1              1    1/1/2016
1              4    2/1/2016
1              5    7/1/2016

有没有办法使用存储过程完成此操作。

DECLARE @A TABLE (CustomerID INT,VisitID INT,VisitDate DATE)

插入@A VALUES(' 1',' 1',' 1/15 / 2016')                     ,(' 1',' 2',' 2/2 / 2016') ; WITH AS(SELECT ROW_NUMBER()OVER(CONVERT PARERTION(NVARCHAR(2),DATEPART(MONTH,CONVERT(DATE,VisitDate)))由VisitDate订购) row_id,CustomerID,VisitId,VisitDate FROM @A) SELECT CustomerID,VisitId,VisitDate FROM A WHERE row_id = 1

在上面的脚本中,结果条目应仅为' 1/15/2016',作为' 1/15 / 2016'之间的日期差异。和' 2/2 / 2016'不到31天

您提供的SP为前两个条目工作,请您帮助满足以下要求。我发誓这将是我的最后一个问题

  1. (' 2016/1/15'), - -----(这是第1次有效访问)
  2. (' 2/2 / 2016'), - (这是无效访问,因为此次访问是在第一次有效访问后的31天内进行的)
  3. (' 3/2 / 2016'), - -----(这是第一次有效访问后31天发生的第二次有效访问)
  4. (' 2016年3月4日'), - (这是无效访问,因为此次访问是在第二次有效访问后的31天内进行的)
  5. (' 2016年3月15日'), - (这是无效访问,因为此访问发生在第二次有效访问后的31天内)
  6. (' 7/5/2016'), - -----(这是第二次有效访问后31天发生的第三次有效访问)
  7. (' 8/1 2016'), - (这次访问是无效的访问 在第3次有效访问后的31天内发生)
  8. (' 8/7/2016') - -----(这是第4次有效访问,因为此访问发生在第3次有效访问后31天)

1 个答案:

答案 0 :(得分:0)

结帐这个:

DECLARE @A TABLE (CustomerID INT,VisitID INT, VisitDate DATE)
DECLARE @B TABLE (CustomerID INT,VisitID INT, VisitDate DATE)
INSERT INTO @A VALUES('1','1','1/15/2016'),  ('1','2','2/2/2016'), 
('1','3','3/2/2016'),  ('1','4','3/4/2016'), ('1','5','3/15/2016'),
('1','6','7/5/2016'),  ('1','7','8/1/2016'),  ('1','8','8/7/2016') 

DECLARE @starter INT = 0,@counter INT=0,@CustomerID INT,@VisitID INT, @VisitDate DATE,@total INT = (SELECT COUNT(*) FROM @A)

WHILE(@starter<@total)
BEGIN
SELECT @CustomerID=A.CustomerID,@VisitID=A.VisitID,@VisitDate=A.VisitDate,
@counter = ISNULL((DATEDIFF(DAY,B.VisitDate,A.VisitDate)+@counter),0),@starter = @starter + 1
FROM @A A LEFT JOIN (SELECT VisitID+1 VisitID,VisitDate FROM @A 
WHERE VisitID=@starter) B ON A.VisitID = B.VisitID WHERE A.VisitID = @starter+1
IF( @counter = 0 OR @counter > 31)
    BEGIN
    INSERT INTO @B SELECT @CustomerID,@VisitID,@VisitDate
    SET @counter = 0
    END
END

SELECT * FROM @A -- your table
SELECT * FROM @B -- output you desire :)

希望它有所帮助。 :)