2017-09-07 2 views
1

Ich habe Daten wie folgt. Ich möchte über das Zinsfeld aggregieren, während ich die letzten Werte von Balance, Beschreibung und Datum aufnehme.Aggregieren Sie ein Feld und holen Sie den letzten Wert eines anderen Feldes

Daten

Date || AccNum||ID      ||Balance ||Curncy||Interest||Description 
========||=======||=======================||========||======||========||=========== 
7/1/2017|| DEPA1 ||HKGCIFSRCKEY002DEPA1SGD||1000 ||SGD ||0  ||Open 
8/1/2017|| DEPA1 ||HKGCIFSRCKEY002DEPA1SGD||1010 ||SGD ||10  ||Open 
9/1/2017|| DEPA1 ||HKGCIFSRCKEY002DEPA1SGD||1020 ||SGD ||10  ||Closed 
6/1/2017|| DEPA2 ||HKGCIFSRCKEY002DEPA2SGD||10000 ||SGD ||0  ||Open 
7/1/2017|| DEPA2 ||HKGCIFSRCKEY002DEPA2SGD||10100 ||SGD ||100  ||Open 
8/1/2017|| DEPA2 ||HKGCIFSRCKEY002DEPA2SGD||10200 ||SGD ||100  ||Open 
9/1/2017|| DEPA2 ||HKGCIFSRCKEY002DEPA2SGD||10300 ||SGD ||100  ||Dormant 

Erwartetes Ergebnis

Date || AccNum||ID      ||Balance ||Curncy||Interest||Description 
========||=======||=======================||========||======||========||=========== 
9/1/2017|| DEPA1 ||HKGCIFSRCKEY002DEPA1SGD||1020 ||SGD ||20  ||Closed 
9/1/2017|| DEPA2 ||HKGCIFSRCKEY002DEPA2SGD||10300 ||SGD ||300  ||Dormant 

Ich habe über 30M Datensätze verarbeitet werden, um die Leistung auch eine Herausforderung.

+1

Warum zeigen Sie das 2017.07.01 Datum in den erwarteten Ergebnissen für DEPA1? Sollte es nicht der 9/1/2017 sein, da dies die neuesten Daten für dieses Konto sind? – Eli

+0

Danke @Eli! Korrigiert. – SVaidya

Antwort

3

Wir können zwei Windows-Funktionen verwenden, SUM und DENSE_RANK, um die gewünschte Ausgabe zu erhalten. Die Zinsen können über jedes Konto summiert werden, während der Rang jedes Datensatzes in einem Konto zugewiesen werden kann. Bewahren Sie dann den Datensatz aus jeder Gruppe mit dem neuesten Datum auf.

SELECT 
    t.Date, t.AccNum, t.ID, t.Balance, t.Curncy, t.Interest, t.Description 
FROM 
(
    SELECT Date, AccNum, ID, Balance, Curncy, Description, 
     SUM(Interest) OVER (PARTITION BY AccNum) AS Interest, 
     RANK() OVER (PARTITION BY AccNum ORDER BY Date DESC) rank 
    FROM yourTable 
) t 
WHERE t.rank = 1; 

Die meiste Zeit auf Stack-Überlauf Sie wahrscheinlich sehen würde ROW_NUMBER statt RANK verwendet wird. Ich ziehe es vor, eine Art Rang zu verwenden, wenn zwei Datensätze als die jüngsten verknüpft werden. Es ist leicht, Informationen, die Sie nicht wollen, z. eine der Krawatten, aber schwer zu bringen, wenn nicht schon da.

Ausgang:

enter image description here

Demo hier:

Rextester

3

Noch eine weitere Option mit der WITH TIES Klausel

Beispiel

Select Top 1 with Ties 
     Date 
    ,AccNum 
    ,ID 
    ,Balance 
    ,Curncy 
    ,Interest = sum(Interest) over (Partition By AccNum,ID) 
    ,Description 
From YourTable 
Order By Row_Number() over (Partition By AccNum,ID Order By Date Desc) 

Returns

enter image description here

+0

Dies scheint meiner Antwort vorzuziehen, die eine zusätzliche Unterabfrage verwendet. Und wenn Sie Bindungen für jedes Konto auswählen möchten, können Sie einfach eine Rangfunktion anstelle der Zeilennummer +1 verwenden. –

+1

@TimBiegeleisen Danke. Ich habe deinen Kommentar zu RANK vs ROW_NUMBER gesehen. Sie haben Recht, aber es hängt davon ab, wie OP die Ergebnisse verwenden wird. RN würde Doppelzählungen vermeiden. Jedenfalls schon +1 für den RANK Kommentar/Auszeichnung. –

Verwandte Themen