2016-09-09 5 views
1

Wir haben also eine Transaktionstabelle und ich versuche, den letzten Status an Transaktionen anzuhängen, aber ich bin ratlos, wie man mit mehreren Statusänderungen innerhalb eines Tages umgeht. Hier ist ein Beispiel KontoStatusbeschriftung für Transaktionen

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'); 

Hier ist, wie die Daten aussehen sollten

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 

Grundsätzlich muss sie von Transaktionsdatum (auf) sortiert werden, dann Zeit (auf), dann Reihenfolge (absteigend) - Ich habe das schon gemacht.

Ich habe Schwierigkeiten, die neue CurrentStatus-Spalte zu erstellen, die auf den OldStatus/NewStatus-Spalten basieren würde. Wenn es vor einer Statusänderungszeile (eine Zeile, in der Neu/Alt nicht -1 ist) auftritt, verwendet es den ersten OldStatus. Nachdem die erste Statusänderung stattgefunden hat, sollten alle darauf folgenden Zeilen (einschließlich sich selbst) der Status NewStatus der Statusänderung sein. In diesem Fall sollten die Zeilen 2-4 82 sein, und die Zeilen 6-8 sollten 3058 sein. (Diese Daten sind abgekürzt, da es mehr als 50 Transaktionen an einem Tag geben kann, so dass es für mehr als nur 2 Zeilen danach funktionieren muss eine Statusänderung)

+0

"wenn es keine Nicht-1-Werte gibt"? hässlich und verwirrend doppelt negativ. Meinst du "wenn es nur -1 Werte gibt"? ;) –

+0

Wie erhalten Sie die Daten? eine Reihe nach der anderen? oder ein Batch von Zeilen wie bei den Datenwerten, die Sie in Ihrem Beispiel zeigen? Ich glaube, der Trick besteht darin, wie Sie ein INSERT machen würden. –

+0

Leider sind die Daten bereits in der Tabelle. es kommt als eine Nachtcharge herein. Ich berichte nur über die Daten. es wäre schön, Code zu haben, der es korrigiert, wie es hereinkommt. – xenapan

Antwort

1

Wenn ich Sie richtig verstehe, möchten Sie OldStatus verwenden, wenn der vorherige sortierte NewStatus nicht gleich -1 ist. Wenn es gleich -1 ist, dann benutze die aktuellen Zeilen NewStatus. Hier ist eine Möglichkeit, dies zu erreichen.

;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

Wenn Sie sich das Beispiel ansehen, möchte ich tatsächlich alle -1 mit dem neuesten Status ersetzen. Die einzige Ausnahme sind die Transaktionen, die vor einer Statusänderung passieren (dann ist es der erste alte Statuswert, wenn er sich ändert) – xenapan

+0

Ich habe beide Code-Sets ausgeführt und alles was ich sehe ist eine neue aktuelle Statusspalte = neuer Status (und die Zeile Nummer) – xenapan

+0

Wie ermitteln Sie den neuesten Status? Ihre Gruppierungslogik scheint nichts zu passen – scsimon