Повернення набору результатів із кількох рядків на основі максимальної дати


16

У мене є дитячий стіл, який є приблизно таким:

[Таблиця дати зберігання]

| 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, з якою можна пограти, щоб побачити, що дає найкращі показники у вашій ситуації.


Ця відповідь також правильна. На жаль, у мене недостатньо представників, щоб підтвердити це, і мені потрібно вибрати одну відповідь.
Джо DBA
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.