Zwracanie zestawu wyników z wieloma wierszami na podstawie maksymalnej daty

16

Mam stolik dziecięcy, który jest mniej więcej taki:

[Tabela dat Cust]

| 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 |

Chciałbym móc uzyskać taki zestaw wyników - jeden rekord dla każdego klienta z najnowszą datą:

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

Wiem, że mogę to zrobić dla każdego „Identyfikatora klienta” za pomocą następującej składni SQL (SQL Server):

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 |

Ale nie jestem pewien, jak uzyskać wszystkie trzy płyty, które chcę. Nie jestem pewien, czy jest to sytuacja, która wymaga pod-zapytania lub czegoś innego.

Należy pamiętać, że maksymalna data może być inna dla każdego [ID klienta] (w tym przykładzie maksymalna data klienta 3 to 31.03.2012, podczas gdy inne rekordy mają maksymalną datę 2012-04-30). próbowałem

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

Problem polega na tym, że nie zwraca tylko jednego wiersza dla każdego klienta - zwraca wiele wierszy.

Joe DBA
źródło

Odpowiedzi:

18

Po prostu chcesz:

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

Ok - poprawiłeś to. Teraz chcesz zamówić wiersze i wybrać najwyższy:

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
źródło
Och - zmieniłeś pytanie?
Rob Farley
Zmieniłem teraz swoją odpowiedź.
Rob Farley
Jedną zaletą (lub wadą, w zależności od wymagań) tego rozwiązania jest to, że jeśli najnowsza data wystąpi w więcej niż jednym wierszu dla tego samego klienta, nie będzie dublować wyników.
Tim
7

Myślę, że szukasz czegoś takiego

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]

Istnieje wiele odmian tego, tj. CTE, zmienna stołowa, #tabela, z którymi możesz się pobawić, aby zobaczyć, co daje najlepszą wydajność w twojej sytuacji.

WT_W
źródło
Ta odpowiedź jest również poprawna. Niestety nie mam wystarczającej liczby przedstawicieli, aby go głosować i muszę wybrać jedną odpowiedź.
Joe DBA