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

Bor*_*ago 5 sql t-sql

我需要更高级的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
Run Code Online (Sandbox Code Playgroud)

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

CustID   ElapsedDays
  45        327
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢!

Ric*_*iwi 1

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
Run Code Online (Sandbox Code Playgroud)

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

  • 一月的一个,
  • 三月份的一个,
  • 7月A,然后购买
  • 九月 D

它会为客户返回 2 行(1 月和 3 月),因为这两个行都在 6 个多月后进行了 D 购买。

相反,以下查询会查找 LAST A 购买早于 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)
Run Code Online (Sandbox Code Playgroud)

如果对于上述相同的场景,您不想看到该客户,因为 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))
Run Code Online (Sandbox Code Playgroud)