Oracle / Sybase SQL - 根据以前的记录(不是简单的LAG)获取值

时间:2012-12-12 21:43:27

标签: sql oracle lag

我的数据组织如下:

Invoice_Id  Invoice_Line  Kit_Flag  Part_Number
----------  ------------  --------  -----------
AB12345               1    K        KT-1234A
AB12345               2    C        1234567
AB12345               3    C        1234568
AB12345               4    C        1234569
AB12345               5    C        1234560
AB12345               6    K        KT-1234C
AB12345               7    C        1234561
AB12345               8    C        1234562
AB12345               9    K        KT-1234Q
AB12345              10    C        5678901
AB12345              11    C        1234561
AB12345              12    C        1234562

我试图在单个Invoice_Id(K = Parent,C = Child)中获取Kit_Flag为'K'的最后一行的后续行的Part_Number值。为简单起见,我在此仅列出了一个发票ID。

因此,对于上面的数据,结果将如下所示:

Invoice_Id  Invoice_Line  Kit_Flag  Part_Number Parent_Part
----------  ------------  --------  ----------- ------------
AB12345               1    K        KT-1234A    KT-1234A
AB12345               2    C        1234567     KT-1234A
AB12345               3    C        1234568     KT-1234A
AB12345               4    C        1234569     KT-1234A
AB12345               5    C        1234560     KT-1234A
AB12345               6    K        KT-1234C    KT-1234C
AB12345               7    C        1234561     KT-1234C
AB12345               8    C        1234562     KT-1234C
AB12345               9    K        KT-1234Q    KT-1234Q
AB12345              10    C        5678901     KT-1234Q
AB12345              11    C        1234561     KT-1234Q
AB12345              12    C        1234562     KT-1234Q

在Excel中,这可能是通过“= If(C2 =”K“,C3,D2),”这实际上是我们暂时解决的问题,但我试图自动化这个。

该表位于Oracle 9i和Sybase上,但Sybase实例没有分析功能。

我认为这不会起作用(事实并非如此),但从理论上说它显示了我想要做的事情:

select
  t.Invoice_Id, t.Invoice_Line, t.Kit_Flag, t.Part_Number,
  case
    when Kit_Flag = 'K' then Part_Number
    else lag(Parent_Part, 1) over (partition by Invoice_Id order by Invoice_Line)
  end as Parent_Part
from Invoice_Data t

欢迎任何建议和/或指导。

1 个答案:

答案 0 :(得分:3)

执行此操作的一种方法是使用嵌套排名函数。首先,为获得一个值的所有内容(使用max() over)分配一个常量值,然后将其用作分区。

select t.Invoice_Id, t.Invoice_Line, t.Kit_Flag, t.Part_Number,
       max(KitPart) over (partition by invoice_id, KitNum) as Parent_Part
from (select t.*,
             sum(isKit) over (partition by InvoiceId order by InvoiceLine) as KitNum
      from (select t.Invoice_Id, t.Invoice_Line, t.Kit_Flag, t.Part_Number,
                   (case when Kit_Flag = 'K' then 1 else 0 end) as IsKit,
                   (case when Kit_Flag = 'K' then Part_Number end) as KitPart
            from Invoice_Data t
           ) t
     ) t