Rückgabe einer Ergebnismenge mit mehreren Zeilen basierend auf dem maximalen Datum

16

Ich habe einen Kindertisch, der ungefähr so ​​aussieht:

[Kundendatumstabelle]

| Customer ID | Some Date  | Balance |
+-------------+------------+---------+
|           1 | 2012-04-30 |   20.00 |
|           1 | 2012-03-31 |   50.00 |
|           2 | 2012-04-30 |    0.00 |
|           2 | 2012-03-31 |   10.00 | 
|           3 | 2012-03-31 |   60.00 |
|           3 | 2012-02-29 |   10.00 |

Ich möchte in der Lage sein, eine Ergebnismenge wie diese zu erhalten - einen Datensatz für jeden Kunden mit dem neuesten Datum:

| Customer ID | Some Date  | Balance |
+-------------+------------+---------+
|           1 | 2012-04-30 |   20.00 | 
|           2 | 2012-04-30 |    0.00 |
|           3 | 2012-03-31 |   60.00 |

Ich weiß, dass ich dies für jede einzelne "Kunden-ID" mit der folgenden SQL (SQL Server-Syntax) tun kann:

select top 1  [Some Date], [Customer ID], [Balance]
from [Cust Date Table]
where [Customer ID] = 2
order by [Some Date] desc


| Customer ID | Some Date  | Balance |
+-------------+------------+---------+
|           2 | 2012-04-30 |    0.00 |

Aber ich bin mir nicht sicher, wie ich an alle drei gewünschten Datensätze kommen soll. Ich bin nicht sicher, ob dies eine Situation ist, die eine Unterabfrage oder etwas anderes erfordert.

Beachten Sie, dass das maximale Datum für jede angegebene [Kunden-ID] unterschiedlich sein kann (in diesem Beispiel ist das maximale Datum für Kunde 3 der 31.03.2012, während die anderen Datensätze das maximale Datum für den 30.04.2012 haben). Ich habe versucht

select [Customer ID], MAX([Some Date]) AS [Latest Date], Balance 
from [Cust Date Table] 
group by [Customer ID], Balance; 

Das Problem ist, dass nicht nur eine Zeile für jeden Kunden zurückgegeben wird, sondern mehrere Zeilen.

Joe DBA
quelle

Antworten:

18

Sie wollen einfach:

SELECT
    [Customer ID],
    MAX([Some Date]) AS[Latest Date]
FROM[Cust Date TABLE]
GROUP BY
    [Customer ID];

Ok - du hast es überarbeitet. Sie möchten nun die Zeilen bestellen und die oberste auswählen:

WITH numbered AS (
    SELECT
        [Customer ID],
        [Some Date],
        [Balance],
        ROW_NUMBER() OVER (
            PARTITION BY
                [Customer ID]
            ORDER BY
                [Some Date] DESC
        ) AS rownum
    FROM[Cust Date TABLE]
)
SELECT
    [Customer ID],
    [Some Date],
    [Balance]
FROM numbered
WHERE
    rownum = 1;
Rob Farley
quelle
Oh - du hast die Frage geändert?
Rob Farley
Meine Antwort wurde jetzt geändert.
Rob Farley
Ein Vorteil (oder Nachteil, abhängig von Ihren Anforderungen) dieser Lösung ist, dass, wenn das späteste Datum in mehr als einer Zeile für denselben Kunden liegt, keine doppelten Ergebnisse erzielt werden.
Tim,
7

Ich denke, du bist auf so etwas aus

select c.[customer ID], [some date], balance
from [cust date table] c
inner join 
    ( select [customer ID], MAX([some date]) as maxdate
    from [cust date table]
    group by [customer ID]) c2
on c2.[customer ID] = c.[customer ID]
and c2.maxdate = c.[some date]

Es gibt eine Reihe von Variationen, z. B. CTE, Tabellenvariable, #Tabelle, mit denen Sie herumspielen können, um zu sehen, wie Sie in Ihrer Situation die beste Leistung erzielen.

WT_W
quelle
Diese Antwort ist auch richtig. Leider habe ich nicht genug Repräsentanten, um es zu bewerten, und ich muss eine Antwort auswählen.
Joe DBA