Oracle SQL - 比较多行和日期

时间:2013-08-23 18:43:14

标签: sql oracle

我在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  

我正在尝试编写一个查询来比较客户的购买情况,以便输出是特定客户在两年内在两个不同位置进行购买的每个实例。我特别绊倒了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的购买,因为它们在彼此的2年内位于不同的位置。 CustID = 2被抛弃,因为它们不在2年内。 CustID = 3在两年内有两次购买,但由于它们位于同一位置,因此被抛弃。而且CustID = 4的购买是保留的,因为购买8和9在2年内并且在不同的位置,9和10在2年内并且在不同的位置(我希望保留这些,尽管8和10在同一位置并且不在10年内。)

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

与往常一样,我们将非常感谢任何帮助/指导。

1 个答案:

答案 0 :(得分: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));