具有时差的递归查询

时间:2016-05-10 10:55:51

标签: sql sql-server-2014

这是我在这里的第一篇文章,尽管我是每日读者。 :)

我需要生成一份MS SQL Server 2014报告,该报告显示在不到3天的时间内回来与我做生意的客户。我试过INNER JOINS,但我没有成功。

我想到解决方案的方式是使用以下逻辑:

If product is same
    and if userId is same
    and if action was donedeal but now is new
    and if date diff <= 3 days
    and if type is NOT same
then show results

例如我的数据:

id  orderId userId  type    product date        action
1   1001    654     ordered apple   01/05/2016  new
2   1002    889     ordered peach   01/05/2016  new
3   1001    654     paid    apple   01/05/2016  donedeal
4   1002    889     paid    peach   03/05/2016  donedeal
5   1003    654     ordered apple   03/05/2016  new
6   1004    889     ordered peach   04/05/2016  new
7   1005    122     ordered apple   04/05/2016  new
8   1006    978     ordered peach   04/05/2016  new
9   1005    122     paid    apple   04/05/2016  donedeal
10  1007    122     ordered apple   10/05/2016  new

期望的结果:

id  orderId userId  type    product date        Diff
3   1001    654     paid    apple   01/05/2016  2 days
4   1002    889     paid    peach   03/05/2016  1 day
5   1003    654     ordered apple   03/05/2016  2 days
6   1004    889     ordered peach   04/05/2016  1 day

您能指导我解决这个问题对我有用的功能吗?

提前致谢。

更新

Gordon Linoff给了我下面建议的代码,但由于Type必须不同,我复制了代码并按照下面的方式运行它并且它有效:

选择t。* 从(选择t。*,              最大值(行动=&#39; donedeal&#39;以及键入=&#39;付款&#39;然后日期结束时)                  (按用户划分,按日期的产品订单)作为last_donedealdate       从T      )t action =&#39; new&#39;并键入=&#39; ordered&#39;日期&lt; dateadd(day,3,last_donedealdate)

UNION ALL

选择t。* 从(选择t。*,              最大值(操作=&#39; donedeal&#39;和类型=&#39;有序&#39;然后日期结束时)的情况                  (按用户划分,按日期的产品订单)作为last_donedealdate  从T  )t action =&#39; new&#39;并输入=&#39;付费&#39;日期&lt; dateadd(day,3,last_donedealdate)

1 个答案:

答案 0 :(得分:1)

您可以使用窗口功能。要获取上次完成的交易日期,请将max()partition byorder by一起使用。其余的只是where子句逻辑:

select t.*
from (select t.*,
             max(case when action = 'donedeal' then date end) over
                 (partition by user, product order by date) as last_donedealdate
      from t
     ) t
where action = 'new' and date < dateadd(day, 3, last_donedealdate);