我需要更高级的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)
我需要使用游标并按记录迭代记录,比较日期吗?
如果是这样,光标程序会是什么样的?虽然我已经完成了多年的程序编程,但我还没有使用过游标.
谢谢!
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 个月。如果客户购买了
它会为客户返回 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)
| 归档时间: |
|
| 查看次数: |
2189 次 |
| 最近记录: |