1

很久以前做过类似的事情,但是当我认为我现在正在做同样的事情时,它不起作用。

历史表是帐户发生的事件列表。其中一些事件是状态的变化,在这种情况下,一个多用途的详细信息列会显示新的状态。样本:

... where Event_Type = 'Change_Status';
Acct  Line  Event_Type     Detail
----  ----  -------------  -------
A        1  Change_Status  Created
A        4  Change_Status  Billed
A        7  Change_Status  Paid
A       10  Change_Status  Audited
B        1  Change_Status  Created
B        6  Change_Status  Billed

现在很容易将其连接到自身并获得一个时间表WHERE A.Acct = B.Acct 和 A.Line < B.Line 但有两件事我失败了:

  1. 我还需要捕获最后一个状态,但在那种情况下没有结束(B.*)。我认为左连接会得到它(B.Line 为空),但事实并非如此。
  2. 需要消除跨越多个状态的时期,例如 A-1 到 A-7 尝试了以下两项,但任何一项都消除了一切。

    AND A.LINE = (SELECT Max(Line) FROM Events TEMP  
                  WHERE TEMP.Acct = A.Acct  
                    AND TEMP.Line < B.Line or B.Line is null);    
    AND NOT EXISTS (SELECT Line FROM Events TEMP   
                    WHERE TEMP.Acct = A.Acct  
                      AND TEMP.Line between A.Line and B.Line);  
    

如果其中任何一个不清楚,我需要创建的是有效的

      Acct  Line     Acct  Line  Status
      ----  ----     ----  ----  -------
from  A        1 To  A        4  Created
from  A        4 To  A        7  Billed
from  A        7 To  A       10  Paid
from  A       10 To              Audited
from  B        1 To  B        6  Created
4

1 回答 1

0

我在 postgres 9.1 数据库(所以,ymmv)上对此进行了探索。这是我提出的查询:

select
  x.acct, x.line, y.line, x.status
from
  statchanges x
    left join statchanges y on x.acct = y.acct
                           and y.line > x.line
where
  y.line is null or
  (y.line - x.line =
    (select min(y1.line - x1.line)
     from statchanges x1, statchanges y1
     where x1.acct = x.acct
       and x1.line = x.line
       and x1.acct = y1.acct
       and y1.line > x1.line));

重要区别: 1- 在 join 子句中,我加入 b.line > a.line,而不是 a.line < b.line。这似乎是因为(至少在 postgres 9.1 上)null是在非空值之后排序的,除非另有说明。2-我正在跳过一些障碍以确保我min在子查询中获得正确的结果:进行非常相似的连接(不必进行左连接,因为我们不关心nulls),并制作确保acctline外部查询匹配。

我不确定这是否完全是您正在寻找的,但希望它能给您一些探索的方向。

于 2012-06-08T19:13:26.170 回答