Как удалить дубликаты записей в запросе выбора над предложением

У меня есть таблица транзакций следующим образом в SQL SERVER.

 UserID       TranDate     Amount
    1   |   2015-04-01   |  0
    1   |   2015-05-02   |  5000
    1   |   2015-09-07   |  1000
    1   |   2015-10-01   |  -4000
    1   |   2015-10-02   |  -700
    1   |   2015-10-03   |  252
    1   |   2015-10-03   |  260
    1   |   2015-10-04   |  1545
    1   |   2015-10-05   |  1445
    1   |   2015-10-06   |  -2000

Я хочу запросить эту таблицу, чтобы получить доступный баланс на конкретную дату. Так что я использовал функцию Windowing для этого.

SELECT TransactionDate, 
    SUM(Amount) OVER (PARTITION BY UserId ORDER BY TransactionDate ROWS 
BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM Transactions

Но поскольку в таблице транзакций есть повторяющаяся запись на дату 2015-10-03, она повторяет данные на дату 2015-10-03. Всякий раз, когда наступает та же дата, я ожидаю последнюю запись этой даты с суммированным доступным балансом.

Токовый выход

TransactionDate     AvailableBalance
   2015-04-01      |       0
   2015-05-02      |       5000
   2015-09-07      |       6000
   2015-10-01      |       2000
   2015-10-02      |       1300
   2015-10-03      |       1552
   2015-10-03      |       1804
   2015-10-04      |       3349
   2015-10-05      |       4794
   2015-10-06      |       2794

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

   2015-10-03      |       1552

ЗДЕСЬ моя скрипка sql

2 ответа

Решение

Вы можете SUM перед оконной функцией вроде:

SqlFiddleDemo

WITH cte AS
(
  SELECT TransactionDate, UserId, SUM(Amount) AS Amount
  FROM Transactions
  GROUP BY TransactionDate, UserId
)
SELECT TransactionDate,  
        SUM(Amount) OVER (PARTITION BY UserId ORDER BY TransactionDate ROWS 
    BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS AvailableBalance 
FROM cte

Использование RANGE вместо ROWS,

SQL Fiddle

SELECT
  TransactionDate,  
  SUM(Amount) OVER (
    PARTITION BY UserId 
    ORDER BY TransactionDate 
    RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS AvailableBalance
FROM Transactions;

Этот вариант дает набор результатов, отличный от первоначально запрошенного, но в некоторых случаях он может быть полезен. Этот вариант возвращает то же количество строк, что и в Transactions Таблица. Таким образом, он вернет две строки с 2015-10-03, но для обоих рядов AvailableBalance было бы 1804,

Я просто хотел подчеркнуть, что есть такая опция RANGE, Если вам действительно нужна одна строка в день, то сначала нужно сгруппировать по дням, как указано в ответе по адресу: lad2025.

Другие вопросы по тегам