Member 12770648 Ответов: 2

SQL-оператор, чтобы рассчитать суммовые разницы в качестве противовесов


Уважаемый Эксперт,

Нужно сгенерировать следующий вывод в разностях.


idno tran сумма bal_difference
-------------------------------------------
001 1 200 0
001 2 500 300
001 3 1000 500
001 4 1700 700


Расчет выглядит следующим образом

1. сумма первой записи остается равной нулю
2. Как использовать инструкцию sql для генерации ожидаемого результата (например, bal_difference)


Спасибо

Что я уже пробовал:

Это своеобразная проблема, проверенная на возможные варианты, но не найденная.

CHill60

Фраза, которую вы ищете, - " running total"

2 Ответов

Рейтинг:
5

Suvendu Shekhar Giri

Вы можете воспользоваться SELF JOIN сделать это.
Попробуйте что-то вроде следующего-

SELECT a.id, a.[no], a.tran_amount, ISNULL(a.tran_amount-b.tran_amount,0) AS bal_difference
FROM #MyTable a
LEFT JOIN #MyTable b ON b.no=a.no-1


ПОЛНОЕ ТЕСТИРОВАНИЕ ЗАПРОСОМ
CREATE TABLE #MyTable(id VARCHAR(3),[no] INT, tran_amount INT)

INSERT INTO #MyTable 
SELECT '001', 1, 200
UNION
SELECT '001', 2, 500  
UNION
SELECT '001', 3, 1000 
UNION
SELECT '001', 4, 1700  

SELECT a.id, a.[no], a.tran_amount, ISNULL(a.tran_amount-b.tran_amount,0) AS bal_difference
FROM #MyTable a
LEFT JOIN #MyTable b ON b.no=a.no-1


Надеюсь, это поможет :)


CHill60

Опереди меня.

Suvendu Shekhar Giri

Спасибо :)

Maciej Los

Похоже, вы должны изменить свои отношения между самосоединяющимися таблицами на:
ON b.no=a.no-1 AND b.id=a.id
Более подробно в моем ответе.
А4!

Suvendu Shekhar Giri

Согласитесь!
@OP, пожалуйста, следуйте правильному решению, как было предложено.

Спасибо за поправку!

Maciej Los

Всегда пожалуйста, мой друг.
Овации,
Мацей

Рейтинг:
2

Maciej Los

Другой способ достичь этого-использовать: ВЕСТИ[^] и-или ЗАДЕРЖКА[^] функция.
Для получения более подробной информации, пожалуйста, смотрите: SQL SERVER - введение в LEAD и LAG-аналитические функции, введенные в SQL Server 2012 - Journey to SQL Authority with Pinal Dave[^]

Примечание: требуется SQL server 2012 и выше!

Как я уже упоминал в комментарии к решению №1 Сувенду Шекхар Гири[^], вы должны самостоятельно объединить таблицы на обоих полях: idno и tran как суметь сохранить отношения между idno и tran.

Проверьте приведенный ниже пример:

DECLARE @MyTable TABLE(idno VARCHAR(3),[tran] INT, amount INT)
 
INSERT INTO @MyTable (idno, [tran], amount)
VALUES('001', 1, 200),
('001', 2, 500),
('001', 3, 1000),
('001', 4, 1700),
('002', 1, 100),
('002', 2, 300),
('002', 3, 1500),
('002', 4, 1750)
 
--1
SELECT a.idno, a.[tran], a.amount, ISNULL(a.amount-b.amount,0) AS bal_difference
FROM @MyTable a
LEFT JOIN @MyTable b ON b.[tran]=a.[tran]-1

--2
SELECT a.idno, a.[tran], a.amount, ISNULL(a.amount-b.amount,0) AS bal_difference
FROM @MyTable a
LEFT JOIN @MyTable b ON a.idno = b.idno AND b.[tran]=a.[tran]-1


Результат №1 - неправильный результат
idno	tran	amount	bal_difference
001	1	200	0
001	2	500	300
001	2	500	400
001	3	1000	500
001	3	1000	700
001	4	1700	700
001	4	1700	200
002	1	100	0
002	2	300	100
002	2	300	200
002	3	1500	1000
002	3	1500	1200
002	4	1750	750
002	4	1750	250


Результат №2 - правильный результат
idno	tran	amount	bal_difference
001	1	200	0
001	2	500	300
001	3	1000	500
001	4	1700	700
002	1	100	0
002	2	300	200
002	3	1500	1200
002	4	1750	250


Suvendu Shekhar Giri

5ед!
Спасибо за исправление и предложенные ссылки.

Maciej Los

Спасибо.