繁体   English   中英

如何找到购买产品A和D> 6个月的客户?

[英]How find Customers who Bought Product A and D > 6 months apart?

我需要更高级的SQL专家的建议。

我被要求创建一份报告,显示购买产品105的客户以及在6个月后购买产品312的客户。

例如,我有以下Orders表:

RecID   CustID   ProdID   InvoiceDate
  1       20      105      01-01-2009
  2       20      312      01-04-2009
  3       20      300      04-20-2009
  4       31      105      07-10-2005
  5       45      105      10-03-2007
  6       45      300      11-10-2007
  7       45      312      08-25-2008

我需要一份报告来查看此表并返回:

CustID   ElapsedDays
  45        327

我需要使用游标并按记录迭代记录,比较日期吗?

如果是这样,光标程序会是什么样的? 虽然我已经完成了多年的程序编程,但我还没有使用过游标。

谢谢!

你上面有一些好的答案; 自我加入是要走的路。 我想建议你如何最好地考虑这样的问题。 如果您在不同的表中购买了产品A和D,该怎么办? 并不是说你应该以那种方式存储数据,但是你应该以这种方式思考数据。 如果您这样做,您可以将product_a_purchases加入到product_d_purchases上的客户ID并比较日期。 因此, 出于查询的目的 ,这就是您需要制作的内容。 不是一个实际的磁盘表,它是product_a_purchases,而是一个来自您的购买表的记录表,其中仅包含产品A的购买,而产品D的记录表相同。这就是自我加入的地方。

select A.CustID, ElapsedDays = datediff(d, A.InvoiceDate, B.InvoiceDate)
from Orders A
inner join Orders B on B.CustID = A.CustID
    and B.ProdID = 312
    -- more than 6 months ago
    and B.InvoiceDate > dateadd(m,6,A.InvoiceDate)
where A.ProdID = 105

以上查询是对您的要求的简单解释,其中任意购买A(105)和D(312)相隔6个月。 如果客户购买

  • 1月的A,
  • 一个三月,
  • 一个在七月,然后购买
  • D在九月

它将为客户返回2行(1月和3月),因为这两行之后都是6个月以后的D购买。

以下查询将查找在购买FIRST D之前最后一次购买是6个月或更长时间的所有情况。

select A.CustID, ElapsedDays = datediff(d, A.InvoiceDate, B.InvoiceDate)
from (
    select CustID, Max(InvoiceDate) InvoiceDate
    from Orders
    where ProdID = 105
    group by CustID) A
inner join (
    select CustID, Min(InvoiceDate) InvoiceDate
    from Orders
    where ProdID = 312
    group by CustID) B on B.CustID = A.CustID
    -- more than 6 months ago
    and B.InvoiceDate > dateadd(m,6,A.InvoiceDate)

如果对于上述相同的情况,您不希望看到此客户,因为A(7月)和D(9月)购买不是相隔6个月,您可以使用EXISTS过滤器从第一个查询中排除它们。

select A.CustID, ElapsedDays = datediff(d, A.InvoiceDate, B.InvoiceDate)
from Orders A
inner join Orders B on B.CustID = A.CustID
    and B.ProdID = 312
    -- more than 6 months ago
    and B.InvoiceDate > dateadd(m,6,A.InvoiceDate)
where A.ProdID = 105
  AND NOT EXISTS (
    SELECT *
    FROM Orders C
    WHERE C.CustID=A.CustID
    AND C.InvoiceDate > A.InvoiceDate
    and C.InvoiceDate < B.InvoiceDate
    and C.ProdID in (105,312))

你可以通过自我加入来做到这一点:

select a.custid, DATEDIFF(dd, a.invoicedate, b.invoicedate) 
from #t a
inner join #t b 
    on a.custid = b.custid 
        and a.prodid = 105 
        and b.prodid = 312 
where DATEDIFF(dd, a.invoicedate, b.invoicedate) > 180

首先使用#t(别名a)用于第一个产品,第二次使用#t(别名b)用于第二个产品。 这是我用来测试它的脚本:

create table #t (
   recid int,
   custid int,
   prodid int,
   invoicedate date)

insert into #t select 1, 20, 105, '1/1/2009'
insert into #t select 2, 20, 312,'1/4/2009'
insert into #t select 3, 20, 300,'4/20/2009'
insert into #t select 4, 31, 105,'7/10/2005'
insert into #t select 5, 45, 105,'10/3/2007'
insert into #t select 6, 45, 300,'11/10/2007'
insert into #t select 7, 45, 312,'8/25/2008'

select a.custid, DATEDIFF(dd, a.invoicedate, b.invoicedate) 
from #t a
join #t b 
    on a.custid = b.custid 
        and a.prodid = 105 
        and b.prodid = 312 
where DATEDIFF(dd, a.invoicedate, b.invoicedate) > 180

drop table #t

可能这样的东西会起作用:

select CustID, datediff(day, O1.InvoiceDate, O2.InvoiceDate) as ElapsedDays
from Orders O1
   inner join Orders O2 
       on  O1.CustId = O2.CustId
       and dateadd(month, 6, O1.InvoiceDate) <= O2.InvoiceDate
where
   O1.ProdId = 105
   and O2.ProdId = 312

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM