Получите текущий баланс рабочего центра, используя раздел - PullRequest
0 голосов
/ 21 мая 2018

Я пишу скрипт, который будет работать на SQL Server 2014.

У меня есть таблица транзакций, записывающая переводы из одного рабочего места в другое.Упрощенная таблица приведена ниже:

DECLARE @transactionTable TABLE (wono varchar(10),transferDate date
                      ,fromWC varchar(10),toWC varchar(10),qty float)

INSERT INTO @transactionTable
SELECT '0000000123','5/10/2018','STAG','PP-B',10
UNION
SELECT '0000000123','5/11/2018','PP-B','PP-T',5
UNION
SELECT '0000000123','5/11/2018','PP-T','TEST',3
UNION
SELECT '0000000123','5/12/2018','PP-B','PP-T',5
UNION
SELECT '0000000123','5/12/2018','PP-T','TEST',5
UNION
SELECT '0000000123','5/13/2018','PP-T','TEST',2
UNION
SELECT '0000000123','5/13/2018','TEST','FGI',8
UNION
SELECT '0000000123','5/14/2018','TEST','FGI',2

SELECT *, 
    fromTotal = -SUM(qty) OVER(PARTITION BY fromWC ORDER BY wono, transferdate, fromWC),
    toTotal = SUM(qty) OVER(PARTITION BY toWC ORDER BY wono, transferdate, toWC)
FROM @transactionTable
ORDER BY wono, transferDate, fromWC

Я хочу получить текущий баланс fromWC и toWC после каждой транзакции.

Учитывая приведенные выше записи, конечный результат должен быть следующим:

enter image description here

Я считаю, что можно использовать SUM(qty) OVER(PARTITION BY..., но я не уверен, как написать заявление.Когда я пытаюсь получить увеличение и уменьшение, каждая строка всегда приводит к 0.

Как мне написать оператор SUM для достижения желаемых результатов?

ОБНОВЛЕНИЕ

enter image description here

На этом рисунке показана каждая транзакция, итоговое количество WC и выделены соответствующие рабочие центры from и to для каждой транзакции.

Например, глядя на вторую запись 5/11, 3 были перенесены из PP-T в TEST.После транзакции было 5 в PP-B, 2 в PP-T и 3 в TEST.

1 Ответ

0 голосов
/ 21 мая 2018

Я могу приблизиться, кроме начальных сальдо:

SELECT  wono, transferDate, fromWC, toWC, qty,
    SUM( CASE WHEN WC = fromWC THEN RunningTotal ELSE 0 END ) AS FromQTY,
    SUM( CASE WHEN WC = toWC THEN RunningTotal ELSE 0 END ) AS ToQTY
FROM( -- b
    SELECT *, SUM(Newqty) OVER(PARTITION BY WC ORDER BY wono,transferdate, fromWC, toWC) AS RunningTotal
    FROM(-- a
            SELECT wono, transferDate, fromWC, toWC, fromWC AS WC, qty, -qty AS Newqty, 'From' AS RecType
            FROM @transactionTable
            UNION ALL
            SELECT wono, transferDate, fromWC, toWC, toWC AS WC, qty, qty AS Newqty, 'To' AS RecType
            FROM @transactionTable
        ) AS a
    ) AS b
GROUP BY wono, transferDate, fromWC, toWC, qty

Моя логика предполагает, что все сальдо начинаются с 0, поэтому сальдо "STAG" будет -10.

Как запросработает:

  1. «Отключить» входную запись, заданную в записях «От» и «Кому», с количествами, в которых значения «От» не указаны.
  2. Рассчитать промежуточные суммы для каждого «WC».
  3. Объединение «непивотных» записей обратно в исходную форму

Решение 2

WITH CTE
AS(
SELECT *,
    ROW_NUMBER() OVER( ORDER BY wono, transferDate, fromWC, toWC ) AS Sequence
FROM @transactionTable
 ),
 CTE2
 AS( 
 SELECT *,
    fromTotal = -SUM(qty) OVER(PARTITION BY fromWC ORDER BY Sequence),
    toTotal = SUM(qty) OVER(PARTITION BY toWC ORDER BY Sequence)
FROM CTE
 )
SELECT a.Sequence, b.Sequence, c.Sequence, a.wono, a.transferDate, a.fromWC, a.toWC, a.qty, a.fromTotal + ISNULL( b.toTotal, 0 ) AS FromTotal, a.toTotal + ISNULL( c.fromTotal, 0 ) AS ToTotal
FROM CTE2 AS a
    OUTER APPLY( SELECT TOP 1 * FROM CTE2 WHERE wono = a.wono AND Sequence < a.Sequence AND toWC = a.fromWC ORDER BY Sequence DESC ) AS b
    OUTER APPLY( SELECT TOP 1 * FROM CTE2 WHERE wono = a.wono AND Sequence < a.Sequence AND fromWC = a.toWC ORDER BY Sequence DESC ) AS c
ORDER BY a.Sequence

Примечание: Это решение значительно выиграет отстолбец «ID», который отражает порядок транзакций ИЛИ как минимум вам понадобится индекс на wono, transferDate, fromWC, toWC

...