2013-08-23 72 views
1

我正在使用Oracle SQL。假设我有一个列出以下内容的表格。Oracle SQL - 比较多行与日期

PurchaseID CustID  Location  Date 
    1   1   A  8/23/2013 12:00:00 AM 
    2   1   B  8/15/2013 12:00:00 AM 
    3   2   A  5/15/2013 12:00:00 AM 
    4   2   B  1/01/2005 12:00:00 AM 
    5   3   A  1/15/2001 12:00:00 AM 
    6   3   A  1/30/2001 12:00:00 AM 
    7   3   B  8/23/2013 12:00:00 AM 
    8   4   A  5/05/2012 12:00:00 AM 
    9   4   B  8/15/2010 12:00:00 AM 
    10   4   A  9/20/2008 12:00:00 AM 

我想,这样的输出是每一个地方一个特定的客户,使2年之内彼此在两个不同的地点购买实例编写按客户的购买比较查询。特别是在CustID = 3和CustID = 4类型的情况下,特别是在位置/日期难以组合的情况下。查询的输出应该如下所示。

PurchaseID CustID  Location  Date 
    1   1   A  8/23/2013 12:00:00 AM 
    2   1   B  8/15/2013 12:00:00 AM 
    8   4   A  5/05/2012 12:00:00 AM 
    9   4   B  8/15/2010 12:00:00 AM 
    10   4   A  9/20/2008 12:00:00 AM 

在输出中,CustID = 1的购买被返回,因为它们在两年内彼此不同的位置。 CustID = 2被抛出,因为它们不在2年内。 CustID = 3在两年内有两次购买,但因为它们位于同一位置而被抛出。并且CustID = 4的购买被保留,因为购买8和9在两年内并且在不同位置,并且9和10在两年内并且在不同位置(我希望尽管8和10位于同一位置,不在10年内)。

注意:Date列具有Oracle SQL'Date'数据类型。

一如既往,任何帮助/指导将不胜感激。

回答

2

您可以将搜索范围限制为下一个或上一个位置与当前位置不同的情况。然后查看时间差来选择行。

这使得大量使用lag()lead()

select t.PruchaseId, t.CustId, t.Location, t.Date 
from (select t.*, 
      lag(location) over (partition by CustId order by Date) as prevloc, 
      lead(location) over (partition by CustId order by Date) as nextloc, 
      lag(date) over (partition by CustId order by Date) as prevdate, 
      lead(date) over (partition by CustId order by Date) as nextdate 
     from t 
    ) t 
where ((prevloc <> location) and (add_months(prevdate, 2*12) > date)) or 
     ((nextloc <> location) and (add_months(date, 2*12) > nextdate)); 
+0

感谢,伟大工程! – user1895076