我需要更高级的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
我需要使用游标并按记录迭代记录,比较日期吗?
如果是这样,光标程序会是什么样的?虽然我已经完成了多年的程序编程,但我还没有使用过游标。
谢谢!
答案 0 :(得分:2)
你上面有一些好的答案;自我加入是要走的路。我想建议你如何最好地考虑这样的问题。如果您在不同的表中购买了产品A和D,该怎么办?并不是说您应该以这种方式存储数据,但是您应该以这种方式思考数据。如果您这样做,您可以将product_a_purchases加入到product_d_purchases上的客户ID并比较日期。因此,出于查询的目的,这就是您需要制作的内容。不是一个实际的磁盘表,它是product_a_purchases,而是一个来自您的购买表的记录表,其中仅包含产品A的购买,而产品D的记录表相同。这就是自我加入的地方。
答案 1 :(得分: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
以上查询是对您的要求的简单解释,其中A(105)和D(312)的任何购买相隔6个月发生。如果客户购买了
它将为客户返回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个月,您可以使用{{{{{ 1}}过滤器。
EXISTS
答案 2 :(得分:1)
您可以使用自我加入来执行此操作:
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
答案 3 :(得分:0)
这样的事情可能有用:
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