Итоговая сумма с покупками и продажами в столбце запроса - PullRequest
0 голосов
/ 26 августа 2018

У меня есть таблица, подобная приведенной ниже:

Table

Как получить столбец, подобный приведенному ниже, с использованием Transact-SQL (Order By Date)?

enter image description here

Я использую SQL Server 2016.

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Вы должны были бы бросить не менее 10 записей с разными тестовыми примерами, чтобы прояснить точку.

Если у вас уже есть поле Increment id в вашей реальной таблице, тогда CTE не требуется.Поле приращения не обязательно должно быть в последовательном

для Sql Server 2008 и ниже,

DECLARE @T table
(
    Purchase int NULL,
    Sale int NULL
);

INSERT @T
    (Purchase, Sale)
VALUES
    (1000, NULL),
    (NULL, 400),
    (NULL, 400),
    (5000, NULL);

;with CTE as
(
select *
,ROW_NUMBER()OVER(ORDER BY (SELECT NULL))rn 
from @T
)

SELECT c.purchase,c.sale
--,c.rn
,case when rn=1 then c.purchase
else c1.Remained
end Remained
FROM cte c
OUTER APPLY(
SELECT 
sum(isnull(purchase,0))-  sum(isnull(sale,0) )Remained
FROM cte c1 WHERE c1.rn<=c.rn 
)c1
0 голосов
/ 26 августа 2018

То, что вам нужно, называется агрегатной оконной функцией , в частности SUM ... OVER.

Проблема в том, что подобный «промежуточный итог» имеет смысл, только если вы можете определить порядок строк детерминистически. Образцы данных не содержат атрибута, который можно использовать для обеспечения этого необходимого порядка. Сами по себе таблицы не имеют явного порядка.

Если у вас есть что-то вроде столбца с датой вступления, будет работать следующее решение:

DECLARE @T table
(
    EntryDate datetime2(0) NOT NULL,
    Purchase money NULL,
    Sale money NULL
);

INSERT @T
    (EntryDate, Purchase, Sale)
VALUES
    ('20180801 13:00:00', $1000, NULL),
    ('20180801 14:00:00', NULL, $400),
    ('20180801 15:00:00', NULL, $400),
    ('20180801 16:00:00', $5000, NULL);

SELECT
    T.Purchase,
    T.Sale,
    Remaining =
        SUM(ISNULL(T.Purchase, $0) - ISNULL(T.Sale, 0)) OVER (
            ORDER BY T.EntryDate
            ROWS UNBOUNDED PRECEDING)
FROM @T AS T;

Демонстрация: дБ <> скрипка

Использование ROWS UNBOUNDED PRECEDING в рамке окна является сокращением для ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW. Поведение ROWS отличается от w.r.t дубликатов (и, как правило, с лучшими показателями ), чем значение по умолчанию RANGE. Есть веские аргументы, чтобы сказать, что ROWS должно было быть по умолчанию, но это не то, что нам дали ?.

Для получения дополнительной информации см. Как использовать оконные функции Microsoft SQL Server 2012 от Ицик Бен-Гана и его превосходную книгу по теме.

...