Возврат результирующего набора с несколькими строками на основе максимальной даты

16

У меня есть дочерняя таблица, которая выглядит примерно так:

[Таблица даты 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 |

Я хотел бы получить такой набор результатов - по одной записи для каждого клиента с самой последней датой:

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

Я знаю, что могу сделать это для каждого отдельного «идентификатора клиента» с помощью следующего 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 |

Но я не уверен, как получить все три записи, которые я хочу. Я не уверен, если это ситуация, которая требует подзапрос или что-то еще.

Обратите внимание, что максимальная дата может отличаться для любого заданного [идентификатора клиента] (в этом примере максимальная дата клиента 3 - 2012-03-31, тогда как для других записей максимальная дата - 2012-04-30). я пытался

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

Проблема в том, что это не возвращает только одну строку для каждого клиента - оно возвращает несколько строк.

Джо ДБА
источник

Ответы:

18

Вы просто хотите:

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

Хорошо, вы пересмотрели это. Теперь вы хотите упорядочить строки и выбрать верхнюю:

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;
Роб Фарли
источник
О - ты изменил вопрос?
Роб Фарли
Изменил мой ответ сейчас.
Роб Фарли
Одно из преимуществ (или недостатка, в зависимости от ваших требований) этого решения заключается в том, что если последняя дата встречается в нескольких строках для одного и того же клиента, это не приведет к дублированию результатов.
Тим
7

Я думаю, что вы после чего-то вроде этого

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]

Существует несколько вариантов этого, например, CTE, табличная переменная, #table, с которыми вы можете поиграть, чтобы увидеть, что дает вам наилучшую производительность в вашей ситуации.

WT_W
источник
Этот ответ также правильный. К сожалению, у меня недостаточно репутации, чтобы проголосовать, и мне нужно выбрать один ответ.
Джо DBA