Использование ROW_NUMBER () с агрегатными функциями - PullRequest
2 голосов
/ 21 января 2020

Допустим, у меня есть этот запрос:

SELECT id, date, amount, cancelled
FROM transactions

, который дает мне следующие результаты:

id  date     amount   ref
1   01/2019  5.00     a
1   02/2019  10.00    b
1   06/2019  20.00    c
2   10/2019  11.00    d

Если есть повторяющиеся идентификаторы, как я могу получить тот с последняя дата , а также сумма всех сумм и объединенная строка всех полей ref ? Т.е.:

id  date     amount   ref
1   06/2019  35.00    abc
2   10/2019  11.00    d

Вот SQL для получения различных идентификаторов с максимальной датой, но я не уверен, как агрегировать поля сумма / ссылка

WITH data_with_date_sequence AS (
    SELECT
          id
        , date
        , amount
        , ref
        , ROW_NUMBER() OVER(PARTITION BY id ORDER BY date DESC) AS seq
    FROM dbo.SomeTable
)
SELECT
      id
    , date
    , amount
    , ref
FROM data_with_date_sequence
WHERE seq = 1;

Ответы [ 2 ]

1 голос
/ 21 января 2020

Используйте window function с sum():

WITH data_with_date_sequence AS (
    SELECT id, date, amount,
           ROW_NUMBER() OVER(PARTITION BY id ORDER BY date DESC) AS seq,
           SUM(amount) OVER (PARTITION BY id) AS amount,
           STUFF(t.ref, 1, 1, '') AS ref
    FROM dbo.SomeTable st CROSS APPLY
         ( SELECT DISTINCT ','+st1.ref
           FROM SomeTable st1 
           WHERE st1.id = st.id
           FOR XML PATH('')
         ) t(Ref)
)
SELECT id, date, amount, ref
FROM data_with_date_sequence
WHERE seq = 1;

Если вы работаете с последней версией, вы можете использовать STRING_AGG () .

Здесь демо .

1 голос
/ 21 января 2020

Для этого случая использования я не вижу необходимости в оконных функциях. Вместо этого рассмотрите этот запрос агрегирования:

select 
    id, 
    max(date) date, 
    sum(amount) amount,
    string_agg(ref, '') within group (order by date) ref
from mytable
group by id

Примечание: string_agg() было добавлено в SQL Server 2017.

...