Renvoyer un jeu de résultats avec plusieurs lignes en fonction de la date maximale

16

J'ai une table enfant qui ressemble à ceci:

[Tableau des dates de dépôt]

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

J'aimerais pouvoir obtenir un jeu de résultats comme celui-ci - un enregistrement pour chaque client avec la date la plus récente:

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

Je sais que je peux le faire pour chaque "ID client" individuel avec le SQL suivant (syntaxe 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 |

Mais je ne sais pas comment obtenir les trois enregistrements que je veux. Je ne sais pas si c'est une situation qui appelle une sous-requête ou autre chose.

Veuillez noter que la date maximale peut être différente pour tout [ID client] donné (dans cet exemple, la date maximale du client 3 est 2012-03-31 alors que les autres enregistrements ont une date maximale de 2012-04-30). j'ai essayé

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

Le problème est que cela ne renvoie pas seulement une ligne pour chaque client - il renvoie plusieurs lignes.

Joe DBA
la source

Réponses:

18

Vous voulez simplement:

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

Ok - vous l'avez révisé. Vous voulez maintenant commander les rangées et choisir celle du haut:

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
la source
Oh - vous avez changé la question?
Rob Farley
J'ai changé ma réponse maintenant.
Rob Farley
Un avantage (ou inconvénient, selon vos besoins) de cette solution est que si la dernière date se produit sur plusieurs lignes pour le même client, elle ne produira pas de résultats en double.
Tim
7

Je pense que tu veux quelque chose comme ça

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]

Il existe un certain nombre de variantes à ce sujet, à savoir CTE, variable de table, #table, avec lesquelles vous pouvez jouer pour voir ce qui vous donne les meilleures performances dans votre situation.

WT_W
la source
Cette réponse est également correcte. Malheureusement, je n'ai pas assez de représentants pour voter, et je dois choisir une réponse.
Joe DBA