2016-09-09 60 views
1

因此,我们有一个交易表,我试图将最近的状态添加到交易中,但我很难理解如何在一天内处理多个状态更改。下面是一个例子帐户交易的状态标签

CREATE TABLE Status 
([account] bigint, [TransactionDate] datetime, [TransactionTime] int, [Code] varchar(3), [TransactionSequence] int, [OldStatus] int, [NewStatus] int, [TransactionAmount] money); 

INSERT INTO Status 
([account], [TransactionDate], [TransactionTime], [Code], [TransactionSequence], [OldStatus], [NewStatus], [TransactionAmount]) 
VALUES 
(8246, '2015-11-02 00:00:00', 6615, 'RT', 3, -1, -1, -808.21), 
(8246, '2015-11-02 00:00:00', 6615, 'ITD', 2, 00047, 00082, NULL), 
(8246, '2015-11-02 00:00:00', 6615, 'PT', 1, -1, -1, 808.21), 
(8246, '2015-11-02 00:00:00', 6616, 'RT', 3, -1, -1, -808.21), 
(8246, '2015-11-02 00:00:00', 6616, 'ITR', 2, 00047, 03058, NULL), 
(8246, '2015-11-02 00:00:00', 6616, 'PT', 1, -1, -1, 808.21), 
(8246, '2015-11-05 00:00:00', 9600, 'E56', 2, -1, -1, '-121.94'); 

这里是数据应该如何看

account  TransactionDate TransactionTime Code TransactionSequence  CurrentStatus TransactionAmount 
8246  2015-11-02  6615    RT  3     00047   -808.21 
8246  2015-11-02  6615    ITD  2     00082   NULL 
8246  2015-11-02  6615    PT  1     00082   808.21 
8246  2015-11-02  6616    RT  3     00082   -808.21 
8246  2015-11-02  6616    ITR  2     03058   NULL 
8246  2015-11-02  6616    PT  1     03058   808.21 
8246  2015-11-05  9600    E56  2     03058   -121.94 

基本上它需要通过交易日期(ASC),然后时间(ASC),然后顺序进行排序(降序) - 我已经做到了。

我很努力地创建新的CurrentStatus列,该列将基于OldStatus/NewStatus列。如果在状态变化行发生之前(New/Old不是-1的行),它使用第一个OldStatus。第一次状态改变发生后,它后面的所有行(包括它本身)应该是状态改变的NewStatus。在这种情况下,第2-4行应该是82,而第6-8行应该是3058.(这个数据缩写为一天内可能有多达50多笔交易,所以它必须在超过2行后工作状态变化)

+0

“如果没有非-1值”?丑陋和令人困惑的双重否定。你的意思是“如果只有-1值”? ;) –

+0

你如何收到数据?一次一行?或一批行与您在示例中显示的数据值一样?我相信这里的诀窍在于你如何进行INSERT。 –

+0

不幸的是,数据已经在表中。它作为一个过夜批次进来。我只是在做数据报告。如果你看看这个例子,我真的想用最新的状态替换所有的-1,这将是可爱的,有代码纠正它,因为它来。 – xenapan

回答

1

如果我正确理解你,如果以前排序的NewStatus不等于-1,你想使用OldStatus。如果它等于-1,则使用当前行NewStatus。这是实现这一目标的一种方法。

;with cteRowNum as(
select 
    *, 
    Rank() OVER (order by TransactionDate asc, TransactionTime asc, TransactionSequence desc) as RowNumber 
from Status) 

select 
    c.account, 
    c.TransactionDate, 
    c.TransactionTime, 
    c.Code, 
    c.TransactionSequence, 
    c.OldStatus, 
    c.NewStatus, 
    c.TransactionAmount, 
    c.RowNumber, 
    case 
     when c.NewStatus = -1 and c.RowNumber = 1 then lead(c.oldstatus) over(order by c.RowNumber) 
     when c.NewStatus = -1 then Lag(c.NewStatus,c.RowNumber - (select max(RowNumber) from cteRowNum where RowNumber < c.RowNumber and NewStatus <> -1)) over (order by c.RowNumber) 
     else c.NewStatus 
    end as CurrentStatus 
from 
    cteRowNum c 
+0

。唯一的例外是在状态改变发生之前发生的事务(当它改变时它的第一个旧状态值) – xenapan

+0

我运行了两套代码,所有即时消息看到的是一个新的当前状态列=新状态(和行号码) – xenapan

+0

你如何确定最近的状态?您的分组逻辑似乎不适合基于您生成的行号的任何内容 – scsimon